Asp.NET Web API - 405错误 - 不允许使用HTTP谓词访问此页面 - 如何设置处理程序映射

137
我使用ASP.NET Web API编写了REST服务。我试图发送HttpDelete请求,但是我遇到了以下错误:
405-不允许使用HTTP动词访问此页面
我认为我离解决方案很近了,我发现我应该启用IIS远程管理,进入处理程序映射部分,并将DELETE动词添加到适当的位置... 但问题是列表上有很多不同的位置... (类似于这里:http://www.somacon.com/p126.php)
我应该编辑哪个呢?其中一些没有扩展名,例如“ExtensionUrlHandler-Integrated-4.0”,我已经向其添加了DELETE动词,但仍然无法工作...
修改它只是一个瞎猜,所以我应该修改其他位置吗?如果是这样,我应该修改哪个位置?或者还有其他操作步骤吗?
在我的本地服务上,相同的Web服务工作得非常好,因此我想问题出在远程IIS上...
问候。

5
嘿,巴特。你能把答案改成 web.config 的吗?这样比卸载好得多。而且你有很多观众。 - Ashkan S
https://dev59.com/H1kS5IYBdhLWcg3wzJT3#59133377 - Ali Imran
16个回答

457

您无需卸载WebDAV,只需将以下行添加到web.config文件中:

<system.webServer>
  <modules>
    <remove name="WebDAVModule" />
  </modules>
  <handlers>
    <remove name="WebDAV" />
  </handlers>
</system.webServer>

37

这种错误的常见原因是WebDAV。请确保卸载它。


3
禁用无法解决问题,你需要卸载它。 - John_
我可以确认禁用是没有帮助的。@John_ 是对的,你必须卸载。 - Mike L
9
以下是需要翻译的内容:giacomelli在下面的回答应该被标记为这个问题的正确答案;这是一个本地解决方案,不需要您卸载WebDav。 我将其翻译为:giacomelli在下面的回答应该被标记为正确答案;这是一种本地解决方案,无需卸载WebDav即可实现。 - Joseph Woodward
你怎么卸载它(也许我没有安装它)。我已经将代码添加到web.config中,但没有任何变化,通过控制面板>卸载程序浏览,没有显示名为“webDAV”的内容;它被称为其他名称吗? - B. Clay Shannon-B. Crow Raven
1
@B.ClayShannon WebDAV不是一个独立的程序,而是IIS的一个功能。因此,根据您的操作系统,您必须在Windows功能/角色/角色服务/...以及其他他们发明用于分类的地方找到它。但是,如果web.config中的更改没有产生任何差异,那么这意味着您遇到了另一个问题。 - Frédéric
显示剩余2条评论

25

请按以下方式更改您的Web.Config文件

 <system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules runAllManagedModulesForAllRequests="true">
<remove name="WebDAVModule" />
</modules>
<handlers>
<remove name="WebDAV"/>
<remove name="ExtensionlessUrlHandler-Integrated-4.0"/>
<remove name="OPTIONSVerbHandler"/>
<remove name="TRACEVerbHandler"/>
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>

1
添加删除WebDAV和WebDAVMODULE允许PUT和DELETE功能。谢谢。 - Gfw
当我在我的 API 项目的 WebConfig 文件中添加了上述代码时,它有所帮助。 - Baqer Naqvi
谢谢,我只是使用了下一个标签<modules runAllManagedModulesForAllRequests="true"> <remove name="WebDAVModule" /> </modules>。 - Esteban Perez

21

将您的Web.Config文件更改为以下内容。它将像魔术一样发挥作用。

在节点<system.webServer>中添加下面的代码部分

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

添加后,您的 Web.Config 将如下所示:

<system.webServer>
    <validation validateIntegratedModeConfiguration="false" />
    <modules runAllManagedModulesForAllRequests="true">
        <remove name="WebDAVModule"/>
    </modules>
    <httpProtocol>
    <customHeaders>
        <add name="Access-Control-Allow-Origin" value="*" />
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
    </customHeaders>
    </httpProtocol>
    <handlers>
      <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" />
    </handlers>
</system.webServer>

不应该在Allow-Origin中返回*。请参考https://dev59.com/Bmct5IYBdhLWcg3wjuIj#12014554。 - Karlas
@Karlas,请在发表评论和点踩之前先阅读问题。问题并不是关于“允许来源”,而是关于处理HTTP动词的处理程序。 - Santosh Prasad Sah
3
我没有点踩,只是顺便说一句,以防有人把解决方案复制粘贴。 - Karlas
谢谢!对我来说,“runAllManagedModulesForAllRequests =” true“就是解决问题的关键。 - Eddie Fletcher

10

我曾经遇到了这个问题,下面是我解决的方法:

  1. 打开IIS
  2. 选择后端站点

    在此输入图片描述

  3. 在特征视图中:打开处理程序映射

在此输入图片描述

  1. 在处理程序映射窗口中,找到WebDAV

在此输入图片描述

  1. 在编辑模块映射中,打开请求限制

在此输入图片描述

  1. 在此输入图片描述

挽救了我的生命。谢谢。 - deanwilliammills
7
这个方法没有生效,反而导致整个 .Net CORE 站点崩溃。必须进行回滚操作。 - Ravi Ram
2
很遗憾,这是一个不好的解决方案。重新构建整个网站。 - Mayur Jain
@RaviRam您是完全正确的。一旦我尝试了这个解决方案,我就无法连接到任何API调用。我开始收到服务器错误。不适用于.Net 5。 - sasi reka

7

检查您的web.config文件。

<modules>        
        <remove name="WebDAVModule" />    
    </modules> 
      <handlers>
                <remove name="WebDAV" />
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModuleV2" resourceType="Unspecified" />
      </handlers>

无法在网站上使用PUT或DELETE - IIS 10,AspNetCore 2.2应用程序,Angular 9和MVC 3。我像上面的示例一样编辑了web.config(为处理程序使用了name =“WebDAVHandler”)。使用[HttpPut}&[HttpDelete]装饰了MVC方法,但还必须使MVC控制器方法与HTTP动词名称匹配,例如“PUT”匹配到控制器方法“Put()” - 即使使用[FromBody]。 “DELETE”动词匹配“Delete()”方法。否则,会出现405-方法不允许错误。最后,还必须从每个MVC(api)控制器中删除属性[AutoValidateAntiforgeryToken]。登录x-xsrf有效。 - Cwinds

4
如果以上解决方案都没有解决你的问题,比如像我遇到的情况(仍然被我的RestClient模块困扰着,面临405错误),请试着使用Postman或Fiddler这样的工具请求你的Api。我的意思是问题可能出在其他地方,比如请求格式不正确。
我发现我的RestClient模块正在请求一个格式不正确的'Put'操作,带有一个未正确格式化的Id参数:
http://myserver/api/someresource?id=75fd954d-d984-4a31-82fc-8132e1644f78

替代

http://myserver/api/someresource/75fd954d-d984-4a31-82fc-8132e1644f78

不正确格式的请求会导致405错误 - 方法不允许(IIS 7.5)。


我这里情况也是一样的。但是,我的情况是必须通过PUT请求传递一个body。我正在使用Insomnia(类似于Postman)作为客户端工具,它运作得非常好。但是在我的代码中却行不通。有什么想法吗? - Darós

3

不常见,但可能有所帮助。

确保您使用的是来自 System.Web.Http[HttpPut]

我们在一个装饰了 HttpPut 的方法上遇到了 'Method not allowed' 405 错误。

我们的问题似乎不太常见,因为我们无意中使用了 System.Web.Mvc 中的 [HttpPut] 属性,而不是 System.Web.Http。

原因是 ReSharper 建议使用 .Mvc 版本,而当您直接从 ApiController 派生时,通常已经引用了 System.Web.Http,而我们使用了一个扩展 ApiController 的类。


1
如果您使用Web API,则根本不需要装饰控制器方法 - 而是在方法名称中使用动词。 - niico

2

当我调用 Web API 的 POST 方法时,如果参数是基元类型而不是从请求正文中访问的复杂类型,我会遇到这个问题(405 方法不允许)。就像这样:

下面的代码可以工作:

 [Route("update"), Authorize, HttpPost]
  public int Update([FromBody] updateObject update)

这不行:

 [Route("update"), Authorize, HttpPost]
 public int Update(string whatever, int whatever, string whatever)

1
如果路由参数与方法签名中的变量名称不匹配(换句话说,路由为“/api/person/{identity}”,而方法为“public void putPerson(int id){...}”),也可能会发生这种情况。 - RonnBlack

2

如果是IIS 8.0,请检查是否启用了HTTP激活。服务器管理器 -> IIS -> 管理(右上角) -> 添加角色和功能 -> ... -> 进入WCF配置,然后选择HTTP激活。


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