ASP.NET WebApi : (405) Method Not Allowed

匿名 (未验证) 提交于 2019-12-03 01:23:02

问题:

I have a Web Api controller. It behaves very strange. When I use PostMan I can access the POST method on the Web Api but when I use HttpWebRequest from .net it returns (405) Method Not Allowed. I put the Web Api code here:

using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Linq; using System.Net; using System.Net.Http; using System.Web; using System.Web.Http;  namespace MyProject.Controllers {     public class TestController : ApiController     {         [HttpPost]         public int buy(OrderResult value)         {             try             {                 if (value.InvoiceDate != null && value.Result == 1)                 {                     return 0;                 }             }             catch{}              return -1;         }     }      public class OrderResult     {         public int Result { get; set; }         public long InvoiceNumber { get; set; }         public string InvoiceDate { get; set; }         public long TimeStamp { get; set; }     } } 

Here is my WebApiConfig.cs:

using System; using System.Collections.Generic; using System.Linq; using System.Web.Http;  namespace MyProject {     public static class WebApiConfig     {         public static void Register(HttpConfiguration config)         {              config.Routes.MapHttpRoute(                 name: "DefaultApi",                 routeTemplate: "api/{controller}/{action}/{id}",                 defaults: new { action = RouteParameter.Optional, id = RouteParameter.Optional }             );          }     } } 

This is how I send the POST request from another .NET project:

using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Web;  namespace MyProject.Controllers {     public static class WebReq     {         public static string PostRequest(string Url, string postParameters)         {             try             {                 HttpWebRequest myReq = (HttpWebRequest)WebRequest.Create(Url);                 myReq.Method = "POST";                 myReq.Timeout = 30000;                 myReq.Proxy = null;                  byte[] postData = Encoding.UTF8.GetBytes(postParameters);                 myReq.ContentLength = postData.Length;                 myReq.ContentType = "application/x-www-form-urlencoded";                 using (Stream requestWrite = myReq.GetRequestStream())                 {                     requestWrite.Write(postData, 0, postData.Length);                     requestWrite.Close();                     using (HttpWebResponse webResponse = (HttpWebResponse)myReq.GetResponse())                     {                         if (webResponse.StatusCode == HttpStatusCode.OK)                         {                             using (Stream str = webResponse.GetResponseStream())                             {                                 using (StreamReader sr = new StreamReader(str))                                 {                                     return sr.ReadToEnd();                                 }                             }                         }                         return null;                     }                 }             }             catch (Exception e)             {                 var message = e.Message;                 return null;             }         }      } } 

I already added the following code in my web.config:

It is strange because I can send POST request successfully from PostMan. The PostMan send this code to the API.

POST /api/Test/buy HTTP/1.1 Host: domain.com Cache-Control: no-cache Postman-Token: 9220a4e6-e707-5c5f-ea61-55171a5dd95f Content-Type: application/x-www-form-urlencoded  InvoiceDate=28012016&Result=1 

I will appreciate any suggestion to solve the problem.

回答1:

     byte[] postData = Encoding.UTF8.GetBytes(postParameters);             myReq.ContentLength = postData.Length;             myReq.ContentType = "application/x-www-form-urlencoded";             using (Stream requestWrite = myReq.GetRequestStream())             {                 requestWrite.Write(postData, 0, postData.Length); 

You're most likely not sending a proper x-www-form-urlencoded request. You're likely not encoding the data properly from whatever is passed in as postParameters. See Post form data using HttpWebRequest

Since you're not generating a valid OrderResult object according to x-www-form-urlencoded, the route selector does not select your Buy action. This is why you get POST is not allowed.

You would likely get to the controller if you changed OrderResult value = null as it is now an optional parameter. However this isn't what you want, unless you're going to have a weird controller that behaves like:

Buy(OrderResult value = null) {     if(value== null)         value = MyCustomDeserializeFromRequestBody(RequestContext)      ... } 

Ultimately you just really shouldn't use this class there are much better constructs for modern development https://stackoverflow.com/a/31147762/37055 https://github.com/hhariri/EasyHttp off the top of my head



回答2:

I found the solution.

I checked the request by Fiddler.When I send a POST request to API it automatically redirect to the same address with this new parameter AspxAutoDetectCookieSupport=1

How to remove AspxAutoDetectCookieSupport=1

Finally I changed the cookieless="AutoDetect" in web.config to cookieless="UseCookies" and the problem solved.



回答3:

Catch your request with fiddler or something similar, you are probably sending "OPTIONS" method.

That's related to CORS, so I think solution for you will be to Enable Cors on WebAPI

http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!