1

我正在尝试以这种方式处理 MVC5 站点中的 HTTP 错误:

网络配置:

<system.webServer>
    <httpErrors errorMode="Custom" existingResponse="Replace">
      <clear/>
      <error statusCode="403" path="/language/Error/Details/403" responseMode="ExecuteURL"/>
      <error statusCode="404" path="/language/Error/Details/404" responseMode="ExecuteURL"/>
      <error statusCode="500" path="/language/Error/Details/500" responseMode="ExecuteURL"/>
    </httpErrors>
</system.webServer>

错误控制器.cs:

// GET: Error/Details
public ActionResult Details()
{
    /* Setting the language for the errors since it is not possible to handle multi-language errors in the web.config file where the errors are redirected */
    if (!CultureHelper.cultures.Contains(base.culture))
    {
        RouteData.Values["culture"] = CultureHelper.GetCurrentNeutralCulture();
    }

    /* Redirecting uncontrolled errors to 404 error */
    if (RouteData.Values["statusCode"] == null)
    {
        return RedirectToRoute(new { culture = base.culture, controller = "Error", action = "Details", statusCode = 404 });
    }

    /* Preparing the model */
    ErrorViewModel error = ErrorFactory.Create(Convert.ToInt32(RouteData.Values["statusCode"]));


    /* Preparing the view */
    base.SetLanguageFromRoute();

    return View(error);
}

RouteConfig.cs:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
        name: "Default",
        url: "{culture}/{controller}/{action}/{id}",
        defaults: new { culture = CultureHelper.GetCurrentNeutralCulture(), controller = "User", action = "Home", id = UrlParameter.Optional }
    );

    routes.MapRoute(
        name: null,
        url: "{culture}/Error/Details/{statusCode}",
        defaults: new { culture = CultureHelper.GetCurrentNeutralCulture() }
    );
}

我的问题是,当 Details GET 操作被调用时,一旦到达这一行:

if (RouteData.Values["statusCode"] == null)

它总是返回 true,因为没有“statusCode”键,RouteData因为它使用的是 Default 路由而不是 Error 路由,并且statusCode传入的路由名称为“id”(默认路由键)。

我知道我可以只使用默认路由并从 ID 中捕获状态代码,但是当我从其他控制器执行错误时,我有那个自定义路由RedirectToRoute,所以我想在这里使用它。有什么方法可以告诉<httpErrors>我我想使用与默认路由不同的路由吗?

4

1 回答 1

-1

有什么方法可以告诉我我想使用与默认路由不同的路由吗?

是的。有2种方式。

最明智的方法是将特定路由放在一般路由之前,这样您的路由表中就不会出现无法访问的执行路径。这可确保您的传入 URL 被定向到正确的控制器。

这意味着您需要将更具体的自定义路由放在默认路由之前,以便首先对其进行检查。

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Error",
            url: "{culture}/Error/Details/{statusCode}",
            defaults: new { culture = CultureHelper.GetCurrentNeutralCulture() }
        );

        routes.MapRoute(
            name: "Default",
            url: "{culture}/{controller}/{action}/{id}",
            defaults: new { culture = CultureHelper.GetCurrentNeutralCulture(), controller = "User", action = "Home", id = UrlParameter.Optional }
        );
    }

另一种方法是调用时指定路由名称RedirectToRouteResult。请注意,您没有为您的路线命名(它为空),因此除非您按照我上面的方式命名,否则您无法做到这一点。

return RedirectToRoute(
    routeName: "Error", 
    routeValues: new { culture = base.culture, controller = "Error", action = "Details", statusCode = 404 });

这会将您重定向到正确的 URL,但可能仍然无法运行,因为当访问该 URL 时,它仍然会点击您的“默认”路由,因为它匹配此 URL 并首先注册。

于 2016-06-08T14:27:34.820 回答