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>
...