ASP.NET Web API 尝试提供物理目录而不是映射控制器
ASP.NET Web API tries to serve physical directories instead of mapped controllers
我有一个现有的ASP.NET Web API 2 项目,之前在路由前缀/api/
(example.com/api/Users
)下服务,但现在需要直接移动它在根目录下 (example.com/Users
).
问题是现在一些路由与项目根目录中的物理目录匹配,并且 IIS 在发出此类冲突请求时尝试为这些目录提供服务。
项目结构如下所示:
MyApi/
App_Start/
Controllers/
Models/
...
Permissions/
...
Global.asax
Global.asax.cs
...
Web.config
路由使用属性路由映射:config.MapHttpAttributeRoutes();
下面是有问题的控制器的简化示例:
namespace MyApi.Controllers
{
[RoutePrefix("Permissions")]
public class PermissionController
{
[Route("")]
[HttpGet]
[ResponseType(typeof(IEnumerable<Permission>))]
public IHttpActionResult Get()
{
return ...
当向 example.com/Permissions
发出请求时,IIS 首先响应 301
重定向到 example.com/Permissions/
(尾部斜杠),然后响应:
IIS 10.0 Detailed Error
HTTP Error 403.14 - Forbidden
The Web server is configured to not list the contents of this directory.
Detailed Error Information:
Module DirectoryListingModule
Notification ExecuteRequestHandler
Handler StaticFile
Error Code 0x00000000
没有冲突目录名称的所有其他控制器都按预期工作。
我试过启用和禁用 runAllManagedModulesForAllRequests
,我试过像这样添加和删除处理程序:
<add name="ApiURIs-ISAPI-Integrated-4.0" path="*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" preCondition="integratedMode,runtimeVersionv4.0" />
我什至尝试删除 StaticFile
处理程序,但到目前为止我尝试过的都没有奏效。
这是当前的Web.config
。它与 Visual Studio 2015 在创建新的空 Web API 2 项目时默认生成的内容相同:
...
<system.webServer>
<handlers>
<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>
...
那么我可以阻止 IIS 尝试为项目内的物理文件提供服务吗? API 应该只提供从控制器动态生成的内容。
经过反复试验,我似乎找到了解决办法。
此标志使 API 更喜欢控制器而不是目录:
System.Web.Routing.RouteTable.Routes.RouteExistingFiles = true;
Web.config
的变化:
runAllManagedModulesForAllRequests
允许 URL (/Users/firstname.lastmane
) 中的点
- 对于不匹配任何映射路由的物理目录,删除
StaticFile
处理程序将 return 404
错误,而不是 403
错误。
内容:
...
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<remove name="StaticFile" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
...
我有一个现有的ASP.NET Web API 2 项目,之前在路由前缀/api/
(example.com/api/Users
)下服务,但现在需要直接移动它在根目录下 (example.com/Users
).
问题是现在一些路由与项目根目录中的物理目录匹配,并且 IIS 在发出此类冲突请求时尝试为这些目录提供服务。
项目结构如下所示:
MyApi/
App_Start/
Controllers/
Models/
...
Permissions/
...
Global.asax
Global.asax.cs
...
Web.config
路由使用属性路由映射:config.MapHttpAttributeRoutes();
下面是有问题的控制器的简化示例:
namespace MyApi.Controllers
{
[RoutePrefix("Permissions")]
public class PermissionController
{
[Route("")]
[HttpGet]
[ResponseType(typeof(IEnumerable<Permission>))]
public IHttpActionResult Get()
{
return ...
当向 example.com/Permissions
发出请求时,IIS 首先响应 301
重定向到 example.com/Permissions/
(尾部斜杠),然后响应:
IIS 10.0 Detailed Error
HTTP Error 403.14 - Forbidden
The Web server is configured to not list the contents of this directory.
Detailed Error Information:
Module DirectoryListingModule
Notification ExecuteRequestHandler
Handler StaticFile
Error Code 0x00000000
没有冲突目录名称的所有其他控制器都按预期工作。
我试过启用和禁用 runAllManagedModulesForAllRequests
,我试过像这样添加和删除处理程序:
<add name="ApiURIs-ISAPI-Integrated-4.0" path="*" type="System.Web.Handlers.TransferRequestHandler" verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS" preCondition="integratedMode,runtimeVersionv4.0" />
我什至尝试删除 StaticFile
处理程序,但到目前为止我尝试过的都没有奏效。
这是当前的Web.config
。它与 Visual Studio 2015 在创建新的空 Web API 2 项目时默认生成的内容相同:
...
<system.webServer>
<handlers>
<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>
...
那么我可以阻止 IIS 尝试为项目内的物理文件提供服务吗? API 应该只提供从控制器动态生成的内容。
经过反复试验,我似乎找到了解决办法。
此标志使 API 更喜欢控制器而不是目录:
System.Web.Routing.RouteTable.Routes.RouteExistingFiles = true;
Web.config
的变化:
runAllManagedModulesForAllRequests
允许 URL (/Users/firstname.lastmane
) 中的点
- 对于不匹配任何映射路由的物理目录,删除
StaticFile
处理程序将 return404
错误,而不是403
错误。
内容:
...
<system.webServer>
<modules runAllManagedModulesForAllRequests="true" />
<handlers>
<remove name="ExtensionlessUrlHandler-Integrated-4.0" />
<remove name="OPTIONSVerbHandler" />
<remove name="TRACEVerbHandler" />
<remove name="StaticFile" />
<add name="ExtensionlessUrlHandler-Integrated-4.0" path="*." verb="*" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
</handlers>
</system.webServer>
...