以相对路径作为参数的 MVC 路由 - 如何在 link 以扩展名结尾时逃避搜索文件的默认行为?

MVC Routing with relative path as parameter - How to escape the default behavior of searching for a file when link ends with extension?

我正在寻找一种使 MVC 路由隐藏文件上传路径的方法,但考虑到它可能是一个 html 文件 link 到另一个 html文件我需要补偿。

routes.MapRoute(
    name: "GetFile",
    url: "File/{id}/{*path}",
    defaults: new { controller = "Home", action = "GetFile", id = UrlParameter.Optional, path = UrlParameter.Optional }
);

所以这导致 url 例如: http://example.com/Files/5/Folder1/Folder2/Folder3/index.html 如果在该页面上单击 link 会导致:http://example.com/Files/5/Folder1/Folder2/Folder3/index2.html

但目前我的问题是,如果我在混合中添加任何文件扩展名,它就会死掉,因为它正在寻找文件本身,当我需要它时,只需将它作为文本变量传递。

您描述的问题 "if I add any file extension in the mix it dies because it is looking for the file itself" 不是 MVC 问题,而是由于默认的 Web 服务器设置。

在 IIS 中,有一些设置可以控制特定文件扩展名的处理方式。 .html 文件默认直接通过网络服务器提供,因此被 MVC 忽略。您可以通过更改处理程序的默认设置来覆盖此行为。

1。将 web.config 中的 HTTP 处理程序更改为处理 .html 扩展

<system.webServer>
    <handlers>     
        <add name="HtmlFileHandler" path="*.html" verb="GET" type="System.Web.Handlers.TransferRequestHandler" preCondition="integratedMode,runtimeVersionv4.0" />
        <!-- other handlers... -->
    </handlers>
</system.webServer>

2。确保 runAllManagedModulesForAllRequestsfalse

请注意,这是默认设置,因此如果不存在,请不要添加。

<system.webServer>
    <modules runAllManagedModulesForAllRequests="false" />
</system.webServer>

3。添加路线

你有这个(几乎)。但是在路由上使 idpath 可选可能没有任何意义。毕竟,如果您不提供路径,它应该做什么? id 只有在后面没有路径的情况下才是可选的,因此如果它确实是可选的,则您需要创建另一条路线来处理没有 id 的情况。

routes.MapRoute(
    name: "GetFile",
    url: "File/{id}/{*path}",
    defaults: new { controller = "Home", action = "GetFile" }
);

4。路由现有文件

要将文件路由到它们的原始位置,您需要将设置应用于路由,否则如果 URL 与磁盘上的物理文件相同,您将收到错误消息。

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.RouteExistingFiles = true;

    routes.MapRoute(
        name: "GetFile",
        url: "File/{id}/{*path}",
        defaults: new { controller = "Home", action = "GetFile" }
    );

    routes.MapRoute(
        name: "Default",
        url: "{controller}/{action}/{id}",
        defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
}

参考:https://weblogs.asp.net/jongalloway/asp-net-mvc-routing-intercepting-file-requests-like-index-html-and-what-it-teaches-about-how-routing-works