我如何使用其中包含 dot/period 的 MVC5 attribute-based 路由?

How can I use MVC5 attribute-based routes with a dot/period in them?

我基本上有一个 out-of-the box MVC 5.2 应用程序,启用了 attribute-based 路由(从提供的 RouteConfig.RegisterRoutes(RouteCollection routes) 方法调用 routes.MapMvcAttributeRoutes();)。

HomeController 中的内容如下:

    [Route("hello.txt")]
    [Route("hellotxt-testing")]
    public ActionResult ShowFile()
    {
        return Content("Hello world");
    }

我可以成功访问/hellotxt-testing(证明attribute-based路由正常):

但是如果我访问 /hello.txt,我会得到一个 404 页面:

与我去 /hello404 时相比,我在那里得到了不同的 404 页面:

我猜第二个 404 页面来自 ASP.NET,而第一个来自 IIS,它甚至没有将请求传递给 ASP.NET?

我该怎么做才能确保 ASP.NET 获得这些带有句点的 URL?还有其他 'special' 个字符也会导致问题吗?

您看到的错误之间的区别是因为当您尝试访问 /hello.txt IIS 试图访问位于服务器上的静态资源文件时,另一方面 /hello404 只是一条未知路由所以抛出 404。

为确保我是正确的,请尝试在末尾添加斜杠并访问 /hello.txt/,您现在应该会收到 404 错误。

有几种方法可以解决这个问题:

首先你可以试试

<modules runAllManagedModulesForAllRequests="true">

但是这个选项称为 RAMMFAR hurts the performance of web application. 并且有其他后果。

其次 您可以为 IIS 创建规则 URL 重写为 always add trailing slash to each incoming URL's

第三个Dots in URL causes 404 with ASP.NET mvc and IIS

<add name="ApiURIs-ISAPI-Integrated-4.0"
     path="/people/*"
     verb="GET,HEAD,POST,DEBUG,PUT,DELETE,PATCH,OPTIONS"
     type="System.Web.Handlers.TransferRequestHandler"
     preCondition="integratedMode,runtimeVersionv4.0" />

但你不喜欢这个。

第四 尝试创建自定义 http 处理程序以向本主题中的所有请求添加尾部斜线 Add a trailing slash at the end of each url?


如果您需要它在应用程序的许多地方工作,我会选择 second 选项。

但我认为最好的是第三。这种带点的 url 对用户不友好,并且违反 SEO 规则。您应该在公开可用的网站上避免使用它们。所以假设你只需要一个控制器和路由这个选项是最快和最干净的。

我们遇到了同样的问题(尽管不是属性路由),它开始出现在 MVC 4 中,并在之后的每个版本中继续出现。

我们项目的一位贡献者发现了解决方案。恐怕我不能提供太多关于原因的解释,但是删除然后替换 UrlRoutingModule 修复了使用带有 . 的路由时的 404 问题。

<configuration>
    <system.webServer>
        <modules>
            <remove name="UrlRoutingModule-4.0" />
            <add name="UrlRoutingModule-4.0" type="System.Web.Routing.UrlRoutingModule" />
        </modules>
    </system.webServer>
</configuration>

这是大约 2 年前发现的,到目前为止,我们还没有 运行 了解此更改造成的任何负面影响。

顺便说一句 - 如果有人能解释为什么这有效,请分享。