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



我有一个Web Api控制器。它的行为非常奇怪。当我使用PostMan时,我可以在Web Api上访问POST方法,但是当我从.net使用HttpWebRequest时,它返回(405)方法不允许。我把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; }
    }
}

这是我的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 }
            );
        }
    }
}

这是我从另一个 .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;
            }
        }
    }
}

我已经在我的 web.config 中添加了以下代码:

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

这很奇怪,因为我可以从邮递员成功发送 POST 请求。邮递员将此代码发送到 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

我将不胜感激任何解决问题的建议。

我知道

这是一个旧帖子,但也许这可能会帮助其他人。 我刚刚遇到了类似的问题,当我显然在邮递员中发帖时,收到 405 错误"不允许"。 事实证明,我使用 http 而不是 https 提交到 URL。 更改为https修复了它。

我找到了解决方案。

我检查了 Fiddler 的请求。当我向 API 发送 POST 请求时,它会自动重定向到具有此新参数的同一地址AspxAutoDetectCookieSupport=1

如何删除 AspxAutoDetectCookieSupport=1

最后,我将 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);

您很可能没有发送正确的 x-www-form-urlencoding 请求。您可能没有从作为 postParameters 传入的任何内容中正确编码数据。请参阅使用 HttpWebRequest 发布表单数据

由于您没有根据 x-www-form-urlencoded 生成有效的 OrderResult 对象,因此路由选择器不会选择您的Buy操作。这就是为什么你得到 POST 是不允许的。

如果您更改了控制器OrderResult value = null您可能会访问控制器,因为它现在是一个可选参数。但是,这不是您想要的,除非您将拥有一个奇怪的控制器,其行为如下:

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

最终,你真的不应该使用这个类,现代开发有更好的结构 https://stackoverflow.com/a/31147762/37055 https://github.com/hhariri/EasyHttp 在我的头顶上

就我而言,我在项目中有一个与路由(例如沙箱)同名的物理文件夹,并且任何 POST 请求都被 IIS 中的静态文件处理程序拦截(显然),而不是 WebAPI 运行时。

收到误导性的 405 错误而不是更预期的 404,是我花一些时间进行故障排除的原因。

不容易陷入其中,但有可能。希望它对某人有所帮助。

使用小提琴手或类似的东西捕获您的请求,您可能正在发送"选项"方法。

这与 CORS 有关,所以我认为您的解决方案是在 WebAPI 上启用 Cors

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

最新更新