简体   繁体   English

ASP.NET MVC 5-如何更改httpErrors中的路由?

[英]ASP.NET MVC 5 - How can I change the route in httpErrors?

I am trying to handle the HTTP errors in a MVC5 site this way: 我正在尝试以这种方式处理MVC5网站中的HTTP错误:

web.config: web.config:

<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>

ErrorController.cs: ErrorController.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: 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() }
    );
}

My problem is, when the Details GET action gets called, once it reaches this line: 我的问题是,当调用Details GET操作时,一旦到达以下行:

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

It always returns true, because there's no "statusCode" key in RouteData since it's using the Default route instead of the Error route, and the statusCode gets passed in the route with the name "id" (default route key). 它始终返回true,因为RouteData使用默认路由而不是错误路由,因此在RouteData没有“ statusCode”键,并且statusCode在名称为“ id”的路由中传递(默认路由键)。

I know I could just use the default route and catch the Status Code from the ID, but I have that custom route for when I do a RedirectToRoute to an error from other controllers, so I would like to use it here. 我知道我可以使用默认路由并从ID中捕获状态代码,但是当我对其他控制器的错误执行RedirectToRoute时,我具有该自定义路由,因此我想在这里使用它。 Is there any way to tell <httpErrors> that I want to use a different route from the Default one? 有没有办法告诉<httpErrors>我要使用与默认路由不同的路由?

Is there any way to tell that I want to use a different route from the Default one? 有没有办法告诉我我要使用与默认路由不同的路由?

Yes. 是。 There are 2 ways. 有两种方法。

The most sensible way is to put specific routes before general routes so you don't have unreachable execution paths in your route table. 最明智的方法是将特定路由放在通用路由之前,这样您的路由表中就不会有无法访问的执行路径。 This ensures your incoming URLs are directed to the correct controller. 这样可以确保将输入的URL定向到正确的控制器。

That means you need to put the more specific custom route before your default route so it will be checked first. 这意味着您需要默认路由之前放置更具体的自定义路由以便首先对其进行检查。

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

The other way is to specify the route name when calling RedirectToRouteResult . 另一种方法是在调用RedirectToRouteResult时指定路由名称。 Note that you didn't give your route a name (it is null) so there is no way for you to do this unless you name it as I have above. 请注意,您没有给您的路线起一个名字(它为空),因此除非您像我上面那样命名,否则您将无法做到这一点。

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

This will redirect you to the correct URL, but probably still won't function because when the URL is accessed it will still hit your "Default" route since it matches this URL and is registered first. 这会将您重定向到正确的URL,但可能仍然无法正常工作,因为访问该URL时,由于它与该URL匹配且已首先注册,因此仍会打“默认”路由。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM