Web API - 405 - 请求的资源不支持http方法'PUT'

时间:2014-05-06 18:26:14

标签: c# rest asp.net-web-api handler

我有一个Web API项目,我无法启用" PUT / Patch"要求反对它。

我从小提琴手得到的回应是:


HTTP/1.1 405 Method Not Allowed
Cache-Control: no-cache
Pragma: no-cache
Allow: GET,POST,DELETE
Content-Type: application/json; charset=utf-8
Expires: -1
Server: Microsoft-IIS/8.0
X-AspNet-Version: 4.0.30319
X-SourceFiles: =?UTF-8?B?QzpcUHJvamVjdHNcZG90TmV0XFdlYkFQSVxBZFNlcnZpY2VcQWRTZXJ2aWNlXGFwaVxpbXByZXNzaW9uXDE1?=
X-Powered-By: ASP.NET
Date: Tue, 06 May 2014 14:10:35 GMT
Content-Length: 72

{"message":"The requested resource does not support http method 'PUT'."}

根据上述回应," PUT"动词不被接受。但是,我无法弄清楚相关处理程序的配置位置。

" Put"类的方法声明如下:

[HttpPatch]
[HttpPut]
public HttpResponseMessage Put(Int32 aID, [FromBody] ImpressionModel impressionModel)
{
     bla, bla, bla, bla
}

我已阅读并实施了以下主题中解释的更改: - Asp.NET Web API - 405 - HTTP verb used to access this page is not allowed - how to set handler mappings - http://www.asp.net/web-api/overview/testing-and-debugging/troubleshooting-http-405-errors-after-publishing-web-api-applications

没有任何工作,因为我在尝试发布" PUT"时仍然得到405响应。命令我的Web API项目。

我甚至评论了所有"处理程序"在ApplicationsHost.config文件中。

使用VS2012 Premium和IIS Express(我假设它是第8版)。我也尝试了VS Dev Server,但也给了我同样的结果。

我没有想法。任何帮助将不胜感激。

谢谢李

10 个答案:

答案 0 :(得分:22)

您使用的是属性路由吗?

此神秘错误是路由属性问题。这在您的WebAPIConfig中启用为:

 config.MapHttpAttributeRoutes(); 

事实证明,Web Api控制器"不能混合使用基于动词的动作方法和传统的动作名称路由。 &#34 ;; https://aspnetwebstack.codeplex.com/workitem/184

简而言之:我需要使用[Route]属性在API控制器中标记我的所有操作,否则操作将被隐藏" (405' d)尝试通过传统路由找到它时。

API控制器:

[RoutePrefix("api/quotes")]
public class QuotesController : ApiController
{
    ...

    // POST api/Quote
    [ResponseType(typeof(Quote))]
    [Route]
    public IHttpActionResult PostQuote(Quote quote)
    {
        if (!ModelState.IsValid)
        {
            return BadRequest(ModelState);
        }

        db.Quotes.Add(quote);
        db.SaveChanges();

        return CreatedAtRoute("", new { id = quote.QuoteId }, quote);
    }

注意:我的路线未命名,因此CreatedAtRoute()名称只是一个空字符串。

WebApiConfig.cs:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Web API configuration and services
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

        // Web API routes
        config.MapHttpAttributeRoutes();

        config.Routes.MapHttpRoute(
            name: "DefaultApi",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );

    }
}

希望这会有所帮助

答案 1 :(得分:10)

我和你有完全相同的问题,我尝试了你尝试过的所有东西,但有时解决方案是如此微不足道,在你的鼻子下,你只是不指望它并继续寻找更复杂的原因。确保在您调用的URL中测试Web方法时,param名称与控制器方法声明中的名称匹配。通过简单地执行此操作(我使用查询参数)解决了我的405问题:

我的客户控制器:

...

[HttpPut]
public string PutClient(string username = "", string phone= ""){...}

在我的WebApiConfig上:

// Web API routes
config.MapHttpAttributeRoutes();

config.Routes.MapHttpRoute(
     name: "DefaultApi",
     routeTemplate: "api/{controller}"
);

用于测试方法的路径必须如此:(使用Postman或类似方法,应用正确的Web方法)

http://localhost:49216/api/clients?username=Kurt&phone=443332211

否则,您将在该控制器中获得该方法的405。我根本不需要更改web.config(无需删除webdav等等)。在文档中查看this的来源:

  

例如,请考虑以下操作:

     

public void Get(int id)

     

id参数绑定到URI。因此,   此操作只能匹配包含“id”值的URI,   无论是在路线词典中还是在查询字符串中。

     

可选参数是一个例外,因为它们是可选的。对于   一个可选参数,如果绑定无法从中获取值,则可以   URI。

答案 2 :(得分:2)

当我更改PUT方法的第一个参数名称

时发生了这种情况
public void Put(int code, [FromBody]Lead lead)

应该是:

public void Put(int id, [FromBody]Lead lead)

这就是它被调用的方式:

$.ajax({
    type: "PUT",
    data: json,
    url: "../api/leadsapi/123",
    contentType: "application/json; charset=utf-8"
});

答案 3 :(得分:1)

如果您忘记在API控制器上公开Put()方法,这也是返回的错误消息。事后看来这是显而易见的,但却让我头疼十分钟。

答案 4 :(得分:1)

有同样的问题,我需要做3件事来解决这个问题:

  1. <modules><handlers>
  2. 中停用了Webdav
  3. 使用WebAPI时,确保HttpPut来自System.Web.Http,而不是来自System.Web.Mvc
  4. 像这样启用ExtensionlessUrlHandler
  5. <remove name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" />

    <remove name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" />

    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />

    <add name="ExtensionlessUrlHandler-ISAPI-4.0_32bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" responseBufferLimit="0" />

    <add name="ExtensionlessUrlHandler-ISAPI-4.0_64bit" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" responseBufferLimit="0" />

    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

    希望这可以帮助你们中的一些人解决这个令人讨厌的问题...

答案 5 :(得分:1)

这个答案为我解决了这个问题。我不得不添加Route属性,问题解决了。

    [HttpPut]
    [Route("")]
    public HttpResponseMessage MyMethod()

答案 6 :(得分:0)

您应该在webservers配置中配置它。这取决于网络服务器的类型,您可以在哪里执行此操作。例如,通过IIS,您可以使用web.config文件在文档根目录中执行此操作。通过跨源请求,您必须将CORS标头添加到响应中,以允许来源,方法等...

注意:也许您可以使用ASP.NET框架对此做些什么,但我认为它不同。

答案 7 :(得分:0)

在web.config中的Handler部分下添加以下部分:

<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,POST,PUT,PATCH,MERGE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />

例如:

<handlers>
    <remove name="WebDAV" />
    <remove name="ExtensionlessUrlHandler-Integrated-4.0" />
    <remove name="OPTIONSVerbHandler" />
    <remove name="TRACEVerbHandler" />
    <add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="GET,POST,PUT,PATCH,MERGE" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>

答案 8 :(得分:0)

现在可能已经很晚了,但有人可以使用它。

我想使用PUT请求,我只是将字符串化对象发送到web api,而put方法只接受该对象。

<强> JQUERY

let musterija = {
            Name: name,
            Email: email,
            Password: password,
            Username: logUser.Username,
            Lastname: lastname,
            GenderString: gender,
            Jmbg: identification,
            PhoneNumber: phone,
        };

        $.ajax({
            method: "PUT",
            url: "/api/Musterija",
            data: JSON.stringify(musterija),
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: function () {
                alert("Entity updated");
                EmptyAllInputs();
                $('#divprofile').show();
                $('#divupdate').hide();
            },
            error: function (msg) {
                alert("Fail - " + msg.responseText);
            }
        });

WEB API

    [HttpPut]
    public HttpResponseMessage PutMusterija(Musterija m)

答案 9 :(得分:0)

对我来说,就像其他海报所声称的那样。很有可能您已在webapiconfig中正确设置了所有设置,但是您只是缺少了一些愚蠢的东西。

在我的情况下,我将路线定义为:

[HttpPut]
    [Route("api/MilestonePut/{Milestone_ID}")]
    public void Put(int id, [FromBody]Milestone milestone)
    {
        db.Entry(milestone).State = System.Data.Entity.EntityState.Modified;
        db.SaveChanges();
    }

看到问题了吗?该参数在路径中定义为Milestone_ID,但在函数本身中定义为id。您可能会认为.NET足够聪明,可以实现这一点,但是它绝对不是,也不会起作用。

一旦将其更改为与参数匹配的方式,如下所示:

[HttpPut]
    [Route("api/MilestonePut/{id}")]
    public void Put(int id, [FromBody]Milestone milestone)
    {
        db.Entry(milestone).State = System.Data.Entity.EntityState.Modified;
        db.SaveChanges();
    }

一切都像魅力一样。