简体   繁体   English

ASP.NET WebApi:(405)方法不允许

[英]ASP.NET WebApi : (405) Method Not Allowed

I have a Web Api controller. 我有一个Web Api控制器。 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. 当我使用PostMan时,我可以在Web Api上访问POST方法,但是当我从.net使用HttpWebRequest时,它返回(405)Method Not Allowed。 I put the Web Api code here: 我把Web Api代码放在这里:

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: 这是我的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: 这是我从另一个.NET项目发送POST请求的方式:

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: 我已经在web.config中添加了以下代码:

<modules runAllManagedModulesForAllRequests="true">
  <remove name="WebDAVModule" />
</modules>

It is strange because I can send POST request successfully from PostMan. 这很奇怪,因为我可以从PostMan成功发送POST请求。 The PostMan send this code to the API. PostMan将此代码发送给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. 我将不胜感激任何解决问题的建议。

I know this is an old post, but maybe this might help someone else. 我知道这是一个老帖子,但也许这可能会帮助其他人。 I just had a similar issue, getting a 405 error "Get not allowed" when I was clearly doing a post in postman. 我刚刚遇到类似的问题,当我明显在邮递员中发帖时,得到405错误“不被允许”。 Turned out, I was submitting to the URL using http instead of https. 原来,我使用http而不是https提交到URL。 Changing to https fixed it. 更改为https修复它。

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 我检查了Fiddler的请求。当我向API发送POST请求时,它会自动重定向到使用此新参数的相同地址AspxAutoDetectCookieSupport=1

How to remove AspxAutoDetectCookieSupport=1 如何删除AspxAutoDetectCookieSupport = 1

Finally I changed the cookieless="AutoDetect" in web.config to cookieless="UseCookies" and the problem solved. 最后我将web.config中的cookieless="AutoDetect"更改为cookieless="UseCookies" ,问题解决了。

     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. 您很可能不会发送正确的x-www-form-urlencoded请求。 You're likely not encoding the data properly from whatever is passed in as postParameters. 您可能无法正确编码从postParameters传入的数据。 See Post form data using HttpWebRequest 请参阅使用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. 由于您未根据x-www-form-urlencoded生成有效的OrderResult对象,因此路由选择器不会选择您的Buy操作。 This is why you get POST is not allowed. 这就是你不允许POST的原因。

You would likely get to the controller if you changed OrderResult value = null as it is now an optional parameter. 如果您更改了OrderResult value = null ,您可能会进入控制器,因为它现在是一个可选参数。 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 最后你真的不应该使用这个类,现代开发有更好的结构https://stackoverflow.com/a/31147762/37055 https://github.com/hhariri/EasyHttp脱离我的头顶

In my case I had a physical folder inside the project with the same name as the route (ex. sandbox) and any POST request was intercepted by the static files handler in IIS (obviously), instead of the WebAPI runtime. 在我的情况下,我在项目中有一个物理文件夹,其名称与路径相同(例如沙盒),任何POST请求都被IIS中的静态文件处理程序(显然)拦截,而不是WebAPI运行时。

Getting a misleading 405 error instead of the more expected 404, was the reason it took me some time to troubleshoot. 得到一个误导性的405错误而不是更多预期的404错误是我花了一些时间进行故障排除的原因。

Not easy to fall-into this, but is possible. 不容易陷入这种情况,但是有可能。 Hope it helps someone. 希望它可以帮助某人。

Catch your request with fiddler or something similar, you are probably sending "OPTIONS" method. 用fiddler或类似的东西捕捉你的请求,你可能正在发送“OPTIONS”方法。

That's related to CORS, so I think solution for you will be to Enable Cors on WebAPI 这与CORS有关,所以我认为你的解决方案是在WebAPI上启用Cors

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM