在MVC中使用自定义404页面的自定义路由

时间:2015-10-14 23:20:18

标签: asp.net-mvc asp.net-mvc-4

我设置了自定义路线:

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();

我还在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();
}

我的真正问题似乎是我做的自定义路由处理程序:

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

它工作正常并正确显示“/ donotexist”等路线的404页面,但不适用于“/ TradeCategories / doesnotexist”等路线。相反,我得到了一个内置的404页面,其中包含“您要查找的资源已被删除,其名称已更改或暂时不可用。”。

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

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

您需要覆盖GLobal.asax

中的Application_Error方法

来自link

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

这应该有效。但是,我宁愿重定向到其他页面,而不是写入Response

this

IController controller = new ErrorPageController();
    controller.Execute(new RequestContext(new HttpContextWrapper(Context), routeData));
    Response.End();
相关问题