ASP.NET MVC - 捕获所有路由和默认路由

问题描述 投票:65回答:8

在尝试让我的应用程序正确生成404错误时,我在路由表的末尾实现了catch all route,如下所示:

 routes.MapRoute(
            "NotFound", _
           "{*url}", _
           New With {.controller = "Error", .action = "PageNotFound"} _
       )

但是,为了使这个工作,我不得不删除默认路由:

{controller}/action/{id}

但是现在已经删除了默认设置,我的大部分操作链接都不再有效,而我找到让它们再次工作的唯一方法是为每个控制器/操作添加单独的路由。

是否有更简单的方法,而不是为每个控制器/操作添加路由?

是否有可能创建一个默认路由,如果用户尝试导航到未知路由,仍然允许捕获所有路由?

asp.net-mvc asp.net-mvc-2
8个回答
100
投票

使用路线约束

在您的情况下,您应该定义您的默认路由{controller}/{action}/{id}并对其进行约束。可能与控制器名称或甚至动作有关。然后把它全部放在它之后它应该工作得很好。

因此,当有人要求资源失败时,catch-all路径将匹配请求。

所以。首先使用路由约束定义默认路由,然后在之后捕获所有路由:

routes.MapRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = UrlParameter.Optional },
    new { controller = "Home|Settings|General|..." } // this is basically a regular expression
);
routes.MapRoute(
    "NotFound",
    "{*url}",
    new { controller = "Error", action = "PageNotFound" }
);

18
投票
//this catches all  requests
routes.MapRoute(
    "Error",
    "{*.}",
     new { controller = "PublicDisplay", action = "Error404" } 
);

在路由表的末尾添加此路由


7
投票

啊,问题是你的默认路由捕获所有3段网址。这里的问题是路由在我们确定谁将处理请求之前运行。因此,任何三个段URL都将匹配默认路由,即使它稍后结束,没有控制器来处理它。

您可以做的一件事是在您的控制器上覆盖HandleMissingAction方法。您还应该使用标记来捕获所有404问题。


2
投票

好吧,我发现没有好办法做到这一点。我已将redirectModecustomErrors属性设置为ResponseRewrite

<customErrors mode="On" defaultRedirect="~/Shared/Error" redirectMode="ResponseRewrite">
    <error statusCode="404" redirect="~/Shared/PageNotFound"/>
</customErrors>

这给了我追求的行为,但没有显示格式化的页面。

对我来说,就SEO而言,这是做得不好。但是,我觉得有一个解决方案,我错过了,因为SO正是我想要发生的事情。 URL保留在失败的页面上并抛出404.在Firebug中检查stackoverflow.com/fail。


1
投票

我建议将其作为最易读的版本。你需要在RouteConfig.cs和一个名为ErrorController.cs的控制器中,它包含一个动作'PageNotFound'。这可以返回一个视图。创建一个PageNotFound.cshtml,它将被返回以响应404:

        routes.MapRoute(
            name:  "PageNotFound",
            url:  "{*url}",
            defaults: new { controller = "Error", action = "PageNotFound" }
        );

怎么读这个:

name: "PageNotFound"

=创建一个新的路径模板,使用任意名称'PageNotFound'

url:"{*url}"

=使用此模板映射所有其他未处理的路线

defaults: new { controller = "Error", action = "PageNotFound" }

=定义错误路径将映射到的操作(错误控制器中的“PageNotFound”操作方法)。这是必需的,因为错误输入的路径显然不会映射到任何操作方法


0
投票

您可能最好在配置部分配置404错误文档,然后恢复默认路由。

FWIW,我认为默认路线要求也是迟钝的。


0
投票

我的解决方案是两个步骤。

我最初通过将此函数添加到我的Global.asax.cs文件来解决此问题:

protected void Application_Error(Object sender, EventArgs e)

我尝试将Server.GetLastError()转换为HttpException,然后检查GetHttpCode。此解决方案详述如下:

ASP.NET MVC Custom Error Handling Application_Error Global.asax?

这不是我得到代码的原始来源。但是,这只能捕获已经路由的404错误。在我的情况下,任何2级URL。

例如,这些URL将显示404页面:

呜呜呜.site.com/blah

呜呜呜.site.com/blah/blah

然而,www.site.com/blah/blah/blah只会说无法找到页面。在我的所有其他路线解决此问题后,添加捕获所有路线:

routes.MapRoute(
            "NotFound",
            "{*url}",
            new { controller = "Errors", action = "Http404" }
        );

但是,NotFound路由似乎不会路由具有文件扩展名的请求。当它们被不同的路线捕获时,这确实有效。


0
投票

如果您正在寻找ASP.NET Core捕获所有路由并在Google上搜索asp.net core catch all route,请点击此处:

ASP.net core MVC catch all route serve static file

© www.soinside.com 2019 - 2024. All rights reserved.