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

我使用 ASP.NET Web API 编写 REST 服务。 我尝试发送 HttpDelete 请求,但是我得到了以下错误:

405-不允许用于访问此页的 HTTP 谓词

我想我已经接近解决方案了,我发现我应该启用 IIS 远程管理,转到 Handler Maps 部分,并将 DELETE 动词添加到适当的位置..。 但问题是名单上有很多不同的职位。 (比如这里: http://www.somacon.com/p126.php)。

我应该剪辑哪一个? 它们中很少有没有扩展名的,例如“ ExtensionUrlHandler-Integration-4.0”,我在其中添加了 DELETE 动词,但它仍然不能工作... ..。

这只是黑暗中的一个镜头来修改那一个,所以我应该修改不同的位置吗?如果有,是哪一个?或者我还应该做些什么?

同样的 Web 服务在我的本地服务上运行得非常好,所以我猜问题出在远程 IIS 上..。

你好

134257 次浏览

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

您不需要卸载 WebDAV,只需将以下代码行添加到 web.config:

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

不常见,但可能有帮助。

确保使用 系统。网络。 Http中的 [ HttpPut ]

我们在 HttpPut 修饰方法上得到了一个“不允许使用的方法”405。

我们的问题似乎并不常见,因为我们不小心使用了 System 的 [ HttpPut ]属性。韦伯。而不是系统。韦伯。哈哈

原因是,再锐建议。Mvc 版本,其中-通常系统。韦伯。当您直接从 苹果控制器派生时,已经引用了 Http,我们使用了一个扩展了 ApiController 的类。

更改 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>

更改 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>

如果上面的解决方案都没有像我这样解决您的问题(仍然停留在我的 RestClient 模块面向405) ,请尝试使用 Postman 或 Fiddler 这样的工具来请求您的 API。我的意思是问题可能在其他地方,比如一个格式不正确的请求。

我发现我的 RestClient 模块正在询问一个带有未格式化的 Id 参数的“ Put”:

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

而不是

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

顺便说一句,格式化错误的请求返回405-Method Not Alallow (IIS 7.5)

在我们的示例中,问题在于。网站和 ADFS。当重定向到 ADFS 端点时,wctx参数需要 WSFederationAuthenticationModule.CreateSignInRequest法: rmidru

感谢 Guillaume Raymond 提供的检查 URL 参数的技巧!

当我正在调用的 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)

除了上述所有解决方案,检查您是否有“ id”或者 DELETE方法中的任何自定义参数与路由配置匹配。

public void Delete(int id)
{
//some code here
}

如果出现重复的405错误,最好将方法签名重置为默认值,如上所示,然后尝试。

默认情况下,路由配置将在 URL 中查找 id。因此,参数名 id在这里很重要,除非您更改 App_Start文件夹下的路由配置。

不过,您可以更改 id的数据类型。

例如,下面的方法应该可以正常工作:

public void Delete(string id)
{
//some code here
}

注意: 还要确保通过 url 没有将数据传递给将有效负载作为正文内容的数据方法。

DELETE http://{url}/{action}/{id}

例如:

DELETE http://localhost/item/1

希望能有帮助。

此错误来自 staticfile 处理程序——默认情况下,它不过滤任何谓词,但可能只能处理 HEAD 和 GET。

这是因为没有其他处理程序站出来说,他们可以处理 DELETE 板。

因为您使用的是 WEBAPI,由于路由没有文件,因此没有扩展名,所以需要在 web.config 文件中添加以下内容:

<system.webserver>
<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="C:\windows\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="C:\windows\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" />

显然什么是 需要取决于经典模式与集成模式,而经典模式取决于位。此外,OPTION 头已经被添加到 CORS 处理中,但是如果你不做 CORS,你就不需要它。

仅供参考,web.config 是应用程序(或应用程序目录)的本地版本,其顶级是 applicationHost.config。

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

我将添加那些卡住试图运行 PHP(Laravel在可能的情况下)或其他独特的 IIS托管与 405 error的情况下,你需要改变的 verbs在处理程序中的具体情况... 因此,因为我使用 PHP我去 PHP处理程序和在 Request Restrictions,然后 Verbs选项卡,添加 verbs你需要的。这是所有我需要添加到 Laravel0启用 Laravel1在 Laravel

<handlers>
<remove name="php-5.6.40" />
<add name="php-5.6.40" path="*.php" verb="GET,HEAD,POST,PUT,DELETE,OPTIONS" modules="FastCgiModule" scriptProcessor="C:\Program Files (x86)\PHP\v5.6\php-cgi.exe" resourceType="Either" requireAccess="Script" />
</handlers>

我遇到了这个问题,我解决了以下问题:

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

    enter image description here

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

enter image description here

  1. 在 Handler Mapping 窗口中,查找 WebDAV

enter image description here

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

enter image description here

  1. enter image description here

以上这些对我来说都不管用,而且我在使用支持页面时遇到了麻烦(https://support.microsoft.com/en-us/help/942051/error-message-when-a-user-visits-a-website-that-is-hosted-on-a-server)then i 比较了应用程序主机文件和其中一个工作副本,似乎我错过了一些处理程序,当我把它们添加回应用程序主机时,它开始工作了。 我错过了所有这些,

<add name="xamlx-ISAPI-4.0_64bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="xamlx-ISAPI-4.0_32bit" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
<add name="xamlx-Integrated-4.0" path="*.xamlx" verb="GET,HEAD,POST,DEBUG" type="System.Xaml.Hosting.XamlHttpHandlerFactory, System.Xaml.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="rules-ISAPI-4.0_64bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="rules-ISAPI-4.0_32bit" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
<add name="rules-Integrated-4.0" path="*.rules" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="xoml-ISAPI-4.0_64bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="xoml-ISAPI-4.0_32bit" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
<add name="xoml-Integrated-4.0" path="*.xoml" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="svc-ISAPI-4.0_64bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness64" />
<add name="svc-ISAPI-4.0_32bit" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v4.0.30319\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv4.0,bitness32" />
<add name="svc-Integrated-4.0" path="*.svc" verb="*" type="System.ServiceModel.Activation.ServiceHttpHandlerFactory, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" preCondition="integratedMode,runtimeVersionv4.0" />
<add name="rules-64-ISAPI-2.0" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" />
<add name="rules-ISAPI-2.0" path="*.rules" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" />
<add name="rules-Integrated" path="*.rules" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
<add name="xoml-64-ISAPI-2.0" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" />
<add name="xoml-ISAPI-2.0" path="*.xoml" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" />
<add name="xoml-Integrated" path="*.xoml" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />
<add name="svc-ISAPI-2.0-64" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework64\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness64" />
<add name="svc-ISAPI-2.0" path="*.svc" verb="*" modules="IsapiModule" scriptProcessor="%windir%\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll" preCondition="classicMode,runtimeVersionv2.0,bitness32" />
<add name="svc-Integrated" path="*.svc" verb="*" type="System.ServiceModel.Activation.HttpHandler, System.ServiceModel, Version=3.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" preCondition="integratedMode,runtimeVersionv2.0" />

检查你的 web.confiq文件”

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

这可能不适用于纯粹的“ Web API”,也可能不适用于流行的面向公众的站点,但是如果您在使用 IIS 10,使用 AspNetCore 2.2、 MVC 2(或3)和 Angular 9构建应用程序的网站上遇到这个错误 405-方法不允许问题,这是我的经验。Msg 错误告诉我可以到达 MVC 控制器,但是在 MVC 控制器上不允许(或找到或列出)“ PUT”作为我的 Http 动词选项之一。

我可以使用 用 POST 登录(因为“ 登入()”是用[ HttpPost (path)]修饰的 MVC 控制器方法的名称) ,而且我可以成功地使用 GET 谓词。我使用导航路线。

但是我 不能使用 POST 来创建一个新条目,PUT 来编辑它们,或者 DELETE 来删除它们。我收到了“405”错误。

对我来说,是 从 web.config 中删除 WebDAV 引用只是将我收到的错误从“405”改为“400-Bad Request”

但是,这个信息也很有帮助,所以我回到开发模式,改变我的 MVC 控制器方法名称,以匹配 HTTP 动词名称,如“ ”现在 火柴控制器 方法“ Put ()”-甚至使用[ FromBody ]。“ 删除”动词现在匹配“ 删除()”方法名称,职位匹配“ 职位()”。我没有从新方法名称中删除或更改任何必要的参数,如“ id”等。

我开始再次测试和 在 dotnet 服务器编译中收到错误显示与 MVC 控制器路径中的跨站点防伪问题的问题。

我还在 StartUp.cs 中使用了防伪 Header/cookies,它可以在登录 POST 中工作,所以我没有在 StartUp.cs 中更改任何内容。

但是我的 MVC 控制器 课程是用 [ AutoValidateAntiforgeryToken ]属性装饰的(不完全理解我为什么要使用它,只是按照我的例子) ,我的 MVC 控制器方法是用[ HttpPut ]装饰的,等等。

因此,由于 dotnet 编译错误,我 被移除了的类级属性为 [ AutoValidateAntiforgeryToken ],而 将[ HttpPut ]等属性保留在方法级别为每个 MVC 控制器。

这是我的解决方案 ,将 web.config 编辑为 删除网上数码声音广播,使控制器 方法名称与 http 谓词匹配删除[ AutoValidateAntiforgeryToken ]属性来自 MVC 控制器类——因为我的网站是私有的,而不是面向公共的。

我在 StartUp.cs 中仍然保留了 Login 头部的 x-xsrf-token/cookies/antiforgery 内容,它在 Login 上仍然可以工作。然而,仍然在研究如何让它在 MVC 控制器类级别上工作。

但是,现在,我可以 POST、 PUT 和 DELETE 而没有错误

更新 -通过阅读一些关于 * * 400-Bad Request 问题的文章,我发现了 这个链接到“ ASP.NET Core Web Api Antiforgery”。非常有帮助。在完成了文章所建议的更新,包括添加 MVC AntiForgeryController 和 Angular Injectable 服务之后,我可以在控制器打开 CRSF 的情况下使用 PUT、 POST 和 DELETE,在大多数控制器上使用“ ValidateAntiForgeryToken”,但是“忽略”一些方法() ,就像文章建议的那样。

除了文章中的修改,我还在我的 StartUp.cs 中的 Configure ()方法中注册了这个应用程序——除了“ login”,我没有面向公众的路径:

        app.Use(nextDelegate => context =>
{
string path = context.Request.Path.Value;
string[] directUrls = { "/<first restricted url route>", "/<second restricted url route>", "/<third>" };
if (path.StartsWith("/api") || string.Equals("/", path) ||
directUrls.Any(url => path.StartsWith(url)))
{
var tokens = antiforgery.GetAndStoreTokens(context);
context.Response.Cookies.Append("XSRF-REQUEST-TOKEN", tokens.RequestToken,
new CookieOptions()
{
HttpOnly = false,
Secure = false,
IsEssential = true
});
}
return nextDelegate(context);
});