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

为了让我的应用程序正确地产生404个错误,我在路由表的末尾实现了一个 catch all path,如下所示:

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

然而,为了让这个工作,我不得不删除默认的路线:

{controller}/action/{id}

但是现在默认设置已经被删除,我的大多数操作链接不再工作,我发现让它们重新工作的唯一方法是为每个控制器/操作添加单独的路由。

有没有比为每个控制器/操作添加路由更简单的方法?

是否有可能创建一个默认路由,在用户尝试导航到未知路由时仍然允许 catch all 路由工作?

77536 次浏览
//this catches all  requests
routes.MapRoute(
"Error",
"{*.}",
new { controller = "PublicDisplay", action = "Error404" }
);

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

我发现没有什么好办法。我已经将 customErrorsredirectMode属性设置为 ResponseRewrite

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

这给了我所需要的行为,但不显示格式化页面。

就搜索引擎优化而言,这对我来说做得很糟糕。然而,我觉得有一个解决方案,我正在错过,因为所以做的正是我想要发生的事情。URL 保留在失败的页面上,并抛出一个404。在 Firebug 中检查 stackoverflow.com/fail。

啊,问题是你的默认路线捕获 所有3段网址。这里的问题是,在我们决定由谁来处理请求之前,Routing 已经运行了很长时间。因此,任何三段 URL 都将匹配默认路由,即使它最终没有控制器来处理它。

您可以在控制器上重写 HandleMissingAction 方法。您还应该使用标记来捕捉所有404个问题。

使用路线约束

在您的情况下,您应该定义您的默认路由 {controller}/{action}/{id},并在其上放置一个约束。可能与控制器名称有关,甚至可能与操作有关。然后把所有的捕获后,它应该工作正常。

因此,当有人请求一个资源失败约束时,“全部捕获”路由将与请求匹配。

因此,首先用路由约束定义默认路由,然后捕获其后的所有路由:

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" }
);

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

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

protected void Application_Error(Object sender, EventArgs e)

尝试将 Server.GetLastError ()强制转换为 HttpException,然后选中 GetHttpCode。 这个解决方案在这里有详细说明:

NET MVC 自定义错误处理 Application _ Error Global.asax? ?

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

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

Www.site.com/blah

Www.site.com/blah/blah

然而, www.site.com/blah/blah/blah 只是说找不到 page。 在我所有其他的路线解决了这个问题之后,加上你所有的路线:

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

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

我推荐这个版本作为最可读的版本。你需要在你的 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" }

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

我尝试了上面所有的模式,但是都没有成功,最后发现 ASP.NET 将我使用的 URL 作为一个静态文件,所以我的请求中没有一个隐藏单个控制器端点。我最终将这个狙击器添加到 web.config 中

<modules runAllManagedModulesForAllRequests="true"/>

然后使用下面的路径匹配模式,解决了这个问题:

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