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

13

我有一个Web Api控制器,它的行为非常奇怪。当我使用PostMan访问Web Api的POST方法时,一切正常,但是当我使用来自.net的HttpWebRequest时,它返回(405)Method Not Allowed错误。我将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>

很奇怪,因为我可以在PostMan中成功发送POST请求。 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

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

5个回答

19

我知道这是一个旧帖子,但也许它可以帮助其他人。当我在Postman中进行POST请求时,明明在执行POST请求,却收到一个405错误“Get not allowed”。结果发现,我提交的URL是使用http而不是https。将其更改为https就解决了该问题。


简洁明了。谢谢Paul。 - Shanks
1
这对我也是一样的情况。重要的是要提到,它不取决于http与https,而很可能是您的代理设置和配置路由请求到某个地方,从而得到此响应。 - halloweenlv

3
我找到了解决方法。
我通过Fiddler检查了请求。当我向API发送POST请求时,它会自动重定向到带有此新参数AspxAutoDetectCookieSupport=1的同一地址。
最后,我在web.config中将cookieless="AutoDetect"更改为cookieless="UseCookies",问题得以解决。 如何删除AspxAutoDetectCookieSupport=1

2
     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-urlencoded请求。你很可能没有正确地对postParameters中传递的数据进行编码。请参见使用HttpWebRequest发布表单数据
由于你没有按照x-www-form-urlencoded的规范生成有效的OrderResult对象,路由选择器不会选择你的Buy操作。这就是为什么你会得到“POST不被允许”的原因。
如果你将OrderResult value = null更改为可选参数,那么你很可能会到达控制器。但是,除非你打算创建一个奇怪的控制器,否则这并不是你想要的。
Buy(OrderResult value = null)
{
    if(value== null)
        value = MyCustomDeserializeFromRequestBody(RequestContext)

    ...
}

最终,您确实不应该使用这个类,因为现代开发有更好的构造方式。我能想到的是https://dev59.com/pW035IYBdhLWcg3wBLXb#31147762https://github.com/hhariri/EasyHttp


1
在我的情况下,项目中有一个与路由同名的物理文件夹(例如sandbox),任何POST请求都会被IIS中的静态文件处理程序拦截(很明显),而不是WebAPI运行时。得到一个误导性的405错误,而不是更加预期的404,这是导致我花费一些时间进行故障排除的原因。
不容易遇到这种情况,但是可能会发生。希望能帮助到某个人。

谢谢,这就是我的问题所在,完全不明显,如果没有这个建议,我不知道该怎么找到它。 - Robert

-2

1
这不是CORS问题,那其实是我的第一个想法,但OP是纯粹从服务器/应用程序运行,而不是在浏览器+ajax中。 - Chris Marisic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接