Asp.net-Mvc-Routing

Response.RedirectToRoute(RouteData.Values) 重定向到區域控制器

  • September 19, 2016

我正在嘗試設置一個 BaseController 來處理文化作為 url 的一部分(基於ASP.NET MVC 5 Internationalization)。只要我禁用我的區域註冊,我的實現就可以正常工作。

註冊我的區域之一時,如果我嘗試輸入錯誤/不受支持的文化 ( http://localhost:52639/zz/ ),我會遇到請求 URL 的 404 錯誤:http://localhost:52639/ FR/測試/發布

我已檢查我的路線是否已正確註冊。

如果我在禁用區域註冊時執行相同操作,則如果我鍵入以下 URL,則基本控制器和路由會正常執行:http://localhost:52639/zz/>我被重定向到<http://localhost:52639/fr/(預設文化)。

這些是我的路線:

public static void RegisterRoutes(RouteCollection routes)
   {
       var namespaces = new[]{typeof(PostController).Namespace};

       routes.IgnoreRoute("favicon.ico");
       routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

       routes.MapRoute("PostToHack", "{culture}/Post/{idAndSlug}", new { culture = "", Controller = "Post", Action = "Show" }, namespaces);
       routes.MapRoute("Post", "{culture}/Post/{id}-{slug}", new { culture = "", Controller = "Post", Action = "Show" }, namespaces);

       routes.MapRoute("TagToHack", "{culture}/Tag/{idAndSlug}", new { culture = "", Controller = "Post", Action = "Tag" }, namespaces);
       routes.MapRoute("Tag", "{culture}/Tag/{id}-{slug}", new { culture = "", Controller = "Post", Action = "Tag" }, namespaces);

       routes.MapRoute("Logout", "{culture}/Logout", new { culture = "", Controller = "Authentication", Action = "Logout" }, namespaces);
       routes.MapRoute("Login", "{culture}/Login", new { culture = "", Controller = "Authentication", Action = "Login" }, namespaces);

       //Error routes
       routes.MapRoute("Error404", "{culture}/errors/404", new { culture = "", Controller = "Errors", Action = "NotFound" }, namespaces);
       routes.MapRoute("Error500", "{culture}/errors/500", new { culture = "", Controller = "Errors", Action = "Error" }, namespaces);

       routes.MapRoute("Home", "{culture}", new { culture = "", Controller = "Post", Action = "Index"},namespaces);

       //Never to be called by user which is why it comes after MapRoute Home so it is always overwritten by it
       routes.MapRoute("Sidebar", "{culture}", new { culture = "", Controller = "Layout", Action = "Sidebar"},namespaces);//This is a "child-only" controller
       routes.MapRoute("NavigationBar", "{culture}", new { culture = "", Controller = "Layout", Action = "NavigationBar"},namespaces);//This is a "child-only" controller

區域路線

public override void RegisterArea(AreaRegistrationContext context)
   {
       var namespaces = new[] { typeof(PostsController).Namespace };

       context.MapRoute(
           "admin_default",
           "{culture}/admin/{controller}/{action}/{id}",
           new { culture = "", action = "Index", id = UrlParameter.Optional }, namespaces
           );
   }

基本控制器:

public class BaseController : Controller
{
   protected override IAsyncResult BeginExecuteCore(AsyncCallback callback, object state)
   {
       var cultureName = RouteData.Values["culture"] as string;

       // Attempt to read the culture cookie from Request
       if (cultureName == null)
           cultureName = (Request.UserLanguages != null) && (Request.UserLanguages.Length &gt; 0)
               ? Request.UserLanguages[0]
               : null; // obtain it from HTTP header AcceptLanguages

       // Validate culture name
       cultureName = CultureHelper.GetImplementedCulture(cultureName); // This is safe


       if (RouteData.Values["culture"] as string != cultureName)
       {
           // Force a valid culture in the URL
           RouteData.Values["culture"] = cultureName.ToLowerInvariant(); // lower case too

           // Redirect user
           Response.RedirectToRoute(RouteData.Values);
       }

       // Modify current thread's cultures            
       Thread.CurrentThread.CurrentCulture = new CultureInfo(cultureName);
       Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture;

       return base.BeginExecuteCore(callback, state);
   }
}

經過更多探勘後,我找到了適合我的解決方案。我的問題來自我註冊路線的順序。我首先註冊了我所在地區的路線:

protected void Application_Start()
   {
       AreaRegistration.RegisterAllAreas();
       RouteConfig.RegisterRoutes(RouteTable.Routes);
   }

我顛倒了順序,並確保我只在以下情況下註冊了我所在區域的路線:

protected void Application_Start()
   {
       RouteConfig.RegisterRoutes(RouteTable.Routes);
       AreaRegistration.RegisterAllAreas();            
   }

引用自:https://stackoverflow.com/questions/39380005