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

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

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

【问题讨论】:

标签: asp.net-mvc routes http-status-code-404


【解决方案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 处理来处理异常。 stackoverflow.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 自从有了这个答案,我发现更好的方法是这个问题中描述的方法:stackoverflow.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");
           }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-10-07
          • 1970-01-01
          • 2019-02-19
          • 1970-01-01
          • 1970-01-01
          • 2017-06-17
          相关资源
          最近更新 更多