ASP.NET Web API 尝试提供物理目录而不是映射控制器

Jar*_*rru 4 c# asp.net iis iis-express asp.net-web-api2

我有一个现有的 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
Run Code Online (Sandbox Code Playgroud)

路由使用属性路由进行映射:config.MapHttpAttributeRoutes();

这是有问题的控制器的简化示例:

namespace MyApi.Controllers
{
    [RoutePrefix("Permissions")]
    public class PermissionController
    {
        [Route("")]
        [HttpGet]
        [ResponseType(typeof(IEnumerable<Permission>))]
        public IHttpActionResult Get()
        {
            return ...
Run Code Online (Sandbox Code Playgroud)

当向 发出请求时example.com/Permissions,IIS 首先响应重定向301example.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
Run Code Online (Sandbox Code Playgroud)

所有其他没有冲突目录名称的控制器都按预期工作。

我尝试过启用和禁用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" />
Run Code Online (Sandbox Code Playgroud)

我什至尝试删除处理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>
...
Run Code Online (Sandbox Code Playgroud)

那么我可以阻止 IIS 尝试为项目内的物理文件提供服务吗?API 应该只提供从控制器动态生成的内容。

Jar*_*rru 5

经过多次尝试和错误,我似乎找到了解决方案。

该标志使 API 更喜欢控制器而不是目录:

System.Web.Routing.RouteTable.Routes.RouteExistingFiles = true;
Run Code Online (Sandbox Code Playgroud)

更改为Web.config

  • runAllManagedModulesForAllRequests允许 URL 中包含点 ( /Users/firstname.lastmane)
  • 对于与任何映射路由不匹配的物理目录,删除StaticFile处理程序将返回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>
...
Run Code Online (Sandbox Code Playgroud)