Asp.net mvc MVC中带有自定义404页面的自定义路由

Asp.net mvc MVC中带有自定义404页面的自定义路由,asp.net-mvc,asp.net-mvc-4,Asp.net Mvc,Asp.net Mvc 4,我已设置了自定义路线: var tradeCategoriesRoute = routes.MapRoute( name: "TradeCategoriesIndex", url: "TradeCategories/{*categories}", defaults: new { controller = "TradeCategories", action = "I

我已设置了自定义路线:

var tradeCategoriesRoute = routes.MapRoute(
     name: "TradeCategoriesIndex",
     url: "TradeCategories/{*categories}",
     defaults:
          new
          {
                controller = "TradeCategories",
                action = "Index"
          },
          namespaces: new[] {"Website.Controllers"}
);
tradeCategoriesRoute.DataTokens["UseNamespaceFallback"] = false;
tradeCategoriesRoute.RouteHandler = new CategoriesRouteHandler();
我还在my Global.asax中设置了一个自定义404页面:

private void Application_Error(object sender, EventArgs e)
{
    var exception = Server.GetLastError();
    var httpException = exception as HttpException;
    DisplayErrorPage(httpException);
}

private void DisplayErrorPage(HttpException httpException)
{
    Response.Clear();
    var routeData = new RouteData();

    if (httpException != null && httpException.GetHttpCode() == 404)
    {
        routeData.Values.Add("controller", "Error");
        routeData.Values.Add("action", "Missing");
    }
    else if (httpException != null && httpException.GetHttpCode() == 500)
    {
        routeData.Values.Add("controller", "Error");
        routeData.Values.Add("action", "Index");
        routeData.Values.Add("status", httpException.GetHttpCode());
    }
    else
    {
        routeData.Values.Add("controller", "Error");
        routeData.Values.Add("action", "Index");
        routeData.Values.Add("status", 500);
    }
    routeData.Values.Add("error", httpException);
    Server.ClearError();
    Response.TrySkipIisCustomErrors = true;
    IController errorController = ObjectFactory.GetInstance<ErrorController>();
    errorController.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    Response.End();
}
它可以正常工作,并正确显示404页面,用于“/doesnotexist”等路由,但不适用于“/TradeCategories/doesnotexist”等路由。相反,我得到了一个内置404页面,页面上显示消息“您正在查找的资源已被删除、名称已更改或暂时不可用。”


如何让我的自定义404页面使用这些自定义路由?

您需要覆盖GLobal.asax中的
应用程序错误
方法

从:


您可能需要研究的是TradeCategories控制器的索引操作的实现。自定义路由和自定义处理程序看起来基本上可以匹配任何路由(TradeCategories/*),因此我猜您的操作或视图中的某些内容会返回404,而不会抛出可以在全局中捕获的异常。asax?

我应该在我的问题中更加明确。我有一个自定义404页面设置使用应用程序错误。问题是它不适用于以我的自定义路由定义的/TradeCategories开头的URL。它只适用于任何不以/TradeCategories开头的路由。@jdehlin在函数Application_Error()中添加一个断点,当您尝试访问/TradeCategories/nonexistingUrl时,应该会看到其中的404错误,这就是问题所在。它不会出现应用程序错误。我明白了。我认为,无论出于何种原因,如果它符合定制路线,它就不会通过管道。
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
    IRouteHandler handler = new MvcRouteHandler();
    var values = requestContext.RouteData.Values;
    if (values["categories"] != null)
        values["categoryNames"] = values["categories"].ToString().Split('/').Where(x => !string.IsNullOrWhiteSpace(x)).ToArray();
    else
        values["categoryNames"] = new string[0];
    return handler.GetHttpHandler(requestContext);
}
void Application_Error(object sender, EventArgs e)
{
  // Code that runs when an unhandled error occurs

  // Get the exception object.
  Exception exc = Server.GetLastError();

  // Handle HTTP errors
  if (exc.GetType() == typeof(HttpException))
  {
    // The Complete Error Handling Example generates
    // some errors using URLs with "NoCatch" in them;
    // ignore these here to simulate what would happen
    // if a global.asax handler were not implemented.
      if (exc.Message.Contains("NoCatch") || exc.Message.Contains("maxUrlLength"))
      return;

    //Redirect HTTP errors to HttpError page
    Server.Transfer("HttpErrorPage.aspx");
  }

  // For other kinds of errors give the user some information
  // but stay on the default page
  Response.Write("<h2>Global Page Error</h2>\n");
  Response.Write(
      "<p>" + exc.Message + "</p>\n");
  Response.Write("Return to the <a href='Default.aspx'>" +
      "Default Page</a>\n");

  // Log the exception and notify system operators
  ExceptionUtility.LogException(exc, "DefaultPage");
  ExceptionUtility.NotifySystemOps(exc);

  // Clear the error from the server
  Server.ClearError();
}
IController controller = new ErrorPageController();
    controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    Response.End();