如何为 ASP.NET MVC 处理“未找到 404 页面”查询的全部路由?

Posted

技术标签:

【中文标题】如何为 ASP.NET MVC 处理“未找到 404 页面”查询的全部路由?【英文标题】:How to make a catch all route to handle '404 page not found' queries for ASP.NET MVC? 【发布时间】:2010-09-23 13:26:06 【问题描述】:

是否可以在 ASP.NET MVC 中创建一个最终路由来捕获所有 .. 并将用户反弹到 404 视图?

注意:我不想在我的 IIS 设置中进行设置。

【问题讨论】:

查看我对“***.com/questions/619895/…”的回答。 【参考方案1】:

自己找到了答案。

Richard Dingwall 有一篇出色的帖子,介绍了各种策略。我特别喜欢 FilterAttribute 解决方案。我不喜欢随意抛出异常,所以我会看看我是否可以改进:)

对于 global.asax,只需将此代码添加为您注册的最后一条路线:

routes.MapRoute(
    "404-PageNotFound",
    "*url",
    new  controller = "StaticContent", action = "PageNotFound" 
    );

【讨论】:

我试过这个,但它不起作用。我已将路由置于我的默认路由下,但仍然出现 404 错误。 假设我对 MVC 很陌生,请您解释一下我到底要做什么。 2 件事。 a) 将最后一条路线添加到您的路线列表中。 b)创建一个控制器(在我的例子中,我称之为StaticContentController)和一个Action方法(在我的例子中,我添加了一个名为PageNotFound(..)的方法)添加逻辑这个方法来显示404页面未找到,查看。 如果您在 RegisterRoutes() 中仍然有默认路由(即 controller/action/id),它将捕获与普通 MVC 请求格式匹配的所有 URL。换句话说,如果它不符合正常格式(blah/blah/blah/blah),catch-all 路由只能拦截错误的 URL。在控制器不存在的情况下,必须通过常规的 ASP.NET 处理来处理异常。 ***.com/questions/619895/… 有很好的处理描述 @RonnBlack 是对的。我通过为每个控制器显式创建一个路由来克服这个问题。但是神奇的*url 仍然没有解决这个问题。如果映射到路由的 URL 可用但控制器/操作本身没有找到怎么办。如果我浏览到 /Home/About123 丑陋的 asp.net 错误页面仍然会出现,因为路由没有到达 *url 但在我的主路由中处理。【参考方案2】:

这个问题最先出现,但更简单的答案出现在后面的问题中:

Routing for custom ASP.NET MVC 404 Error page

我通过创建一个 ErrorController 来进行错误处理 返回本文中的观点。我还必须添加“Catch All” 到 global.asax 中的路线。

如果不是,我看不到它会如何到达这些错误页面中的任何一个 在 Web.config..?我的 Web.config 必须指定:

customErrors mode="On" defaultRedirect="~/Error/Unknown"

然后我还补充说:

error statusCode="404" redirect="~/Error/NotFound"

希望这会有所帮助。

我现在喜欢这种方式,因为它很简单:

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

【讨论】:

这就是我现在所拥有的,但我正在尝试用更好的解决方案替换它,它不会首先向客户端发送 302 响应,而是直接发送 404。将redirectMode更改为ResponseRewrite,您会发现它不再起作用... :-( @LouisSomers 自从有了这个答案,我发现更好的方法是这个问题中描述的方法:***.com/questions/1171035/… 我不希望将用户重定向到不同的 URL,因为它对用户不太友好(甚至我在开发时也觉得很烦人)。干杯。 我收到了错误Config Error: The configuration section 'customErrors' cannot be read because it is missing a section declaration【参考方案3】:

您还可以处理 Global.asax.cs 中的 NOT FOUND 错误,如下所示

protected void Application_Error(object sender, EventArgs e)

    Exception lastErrorInfo = Server.GetLastError();
    Exception errorInfo = null;

    bool isNotFound = false;
    if (lastErrorInfo != null)
    
        errorInfo = lastErrorInfo.GetBaseException();
        var error = errorInfo as HttpException;
        if (error != null)
            isNotFound = error.GetHttpCode() == (int)HttpStatusCode.NotFound;
    
    if (isNotFound)
    
        Server.ClearError();
        Response.Redirect("~/Error/NotFound");// Do what you need to render in view
    

【讨论】:

【参考方案4】:

在您的项目根 web.config 文件下添加此行。

 <system.webServer>
<httpErrors errorMode="Custom" existingResponse="Replace">
  <remove statusCode="404" />
  <error statusCode="404" responseMode="ExecuteURL" path="/Test/PageNotFound" />
  <remove statusCode="500" />
  <error statusCode="500" responseMode="ExecuteURL" path="/Test/PageNotFound" />
</httpErrors>
<modules>
  <remove name="FormsAuthentication" />
</modules>

【讨论】:

谢谢,这正是我所需要的。万一有人遇到和我一样的问题,existingResponse="Replace" 修复了它。我之前在那里设置了自动,这是大多数帖子中建议的选项。我猜在我的情况下 auto 无法确定使用替换。【参考方案5】:

这可能是你使用时的问题

throw new HttpException(404);

当你想抓住它时,我不知道除了编辑你的网络配置之外还有什么其他方法。

【讨论】:

ActionFilters :使用它们来捕获 HttpException。 如果异常不是由控制器动作抛出怎么办?我在控制器工厂中抛出了 404。 那么不确定 - 我不是在玩控制器工厂。苏兹。 Controllerfactory 并不是唯一可能发生这种情况的地方。我将一条捕获所有路由映射到一个仅引发异常的操作方法。异常由 web.config 处理 抛出任何你想要的Exception。让你所有的控制器都派生自一个BaseController。在此 BaseController 中,您覆盖 OnException 并将 filterContext.Result 设置为重定向或查看结果。【参考方案6】:

创建包罗万象的路由的另一种方法是将Application_EndRequest 方法添加到您的MvcApplication per Marco's Better-Than-Unicorns MVC 404 Answer。

【讨论】:

【参考方案7】:

RouterConfig.cs 中添加以下代码:

  routes.MapRoute(
           name: "Error",
           url: "id",
           defaults: new
           
               controller = "Error",
               action = "PageNotFound"

           );

【讨论】:

【参考方案8】:

如果路由无法解析,则 MVC 框架将通过 404 错误.. 最好的方法是使用异常过滤器......创建一个自定义异常过滤器并像这样......

public class RouteNotFoundAttribute : FilterAttribute, IExceptionFilter 
    public void OnException(ExceptionContext filterContext) 
        filterContext.Result  = new RedirectResult("~/Content/RouteNotFound.html");
   

【讨论】:

以上是关于如何为 ASP.NET MVC 处理“未找到 404 页面”查询的全部路由?的主要内容,如果未能解决你的问题,请参考以下文章

如何为 ASP.NET MVC 5 应用程序设置时区?

如何为 Asp.NET MVC 5 创建 ClaimsIdentity 对象?

asp.net MVC 如何为一个视图中某个表单(Form)指定某个提交方法(如CreateRole)

asp.net mvc如何为控制器的动作指定视图

如何为 ASP.net Core 配置 Entity Framework 6

如何为 ASP.NET Core 注册和使用 MediatR 管道处理程序?