Asp.net-Mvc

如何在 MVC 選擇路由之前添加路由參數

  • February 9, 2012

我正在嘗試向現有的 MVC 3 應用程序添加對不同語言的支持。到目前為止,我的連結是

oldUrl -> myapp.com/Item/Details/5/some-title

並且有來自網路上不同地方的網站連結。但現在我想更改 URL,以便包含語言:

newUrl -> kmyapp.com/en/Item/Details/5/some-title

但是我希望 oldUrl 連結有效。問題是我該怎麼做……最簡單的方法是添加另一條路線,但我已經有太多路線了,而且它變得有點難看,當我從一個沒有的頁面創建網址時有語言連結也沒有語言,所以我必須做其他事情。

另一種方法是覆蓋在 MVC 嘗試將請求映射到特定路由之前存在的內容,但已經解析了請求 url 並填充了 routeValues 字典。所以我可以只檢查語言,如果它不包含在路由參數中,我可以自己添加它並呼叫父類的實現以繼續。那可能嗎?我應該看什麼 - UrlRoutingModuleMvcHttpHandler或其他什麼?我可以覆蓋什麼以及如何告訴 MVC 使用我的版本?

任何其他想法也將不勝感激!

另一種方法是覆蓋在 MVC 嘗試將請求映射到特定路由之前存在的內容,但已經解析了請求 url 並填充了 routeValues 字典。所以我可以只檢查語言,如果它不包含在路由參數中,我可以自己添加它並呼叫父類的實現以繼續。那可能嗎?

對的,這是可能的。

您可以 RouteBase中覆蓋GetRouteData ,其中將包含 URL 詳細資訊。

public override RouteData GetRouteData(HttpContextBase httpContext)
{
       string url = httpContext.Request.AppRelativeCurrentExecutionFilePath;
}

並在 global.aspx 中添加以下程式碼。

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

   routes.Add(new MyUrlRoute()); // Add before your default Routes

   routes.MapRoute(
       "Default", // Route name
       "{controller}/{action}/{id}", // URL with parameters
       new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Parameter defaults
   );

有關更詳細的實現 - 請參閱部落格 url-manipulation-implementing-routebase.html

當然有很多解決方案。我要給你看兩個:

  • 您在應用程序中控制的一個
  • 您在應用程序之外控制的一個(在 IIS 上)

解決方案一——Asp.net MVC 路由

提供涵蓋路由和新路由的路由:

routes.MapRoute(
   "New",
   "{lang}/{controller}/{action}/{id}",
   new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional },
   new { lang = "en|de|it|es|fr" }
);
routes.MapRoute(
   "NewEx",
   "{lang}/{controller}/{action}/{id}/{title}",
   new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional, title = UrlParameter.Optional },
   new { lang = "en|de|it|es|fr" }
);

routes.MapRoute(
   "Old",
   "{controller}/{action}/{id}",
   new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional }
);
routes.MapRoute(
   "OldEx",
   "{controller}/{action}/{id}/{title}",
   new { lang = "en", controller = "Home", action = "Index", id = UrlParameter.Optional, title = UrlParameter.Optional }
);

如您所見**,我也為舊路由提供了語言預設值,**因為它不存在於 URL 中。是否要這樣做是您自己的決定,但是這種路由可以不重複您的控制器操作。在任何情況下,您都必須定義一種可以通過這種方式提供的預設語言。

更大的問題是您是否仍想支持舊 URL 或者您更願意重定向它們(HTTP Redirect Permanent Status 301)。

永久重定向

將舊路線更改為:

routes.MapRoute(
   "Old",
   "{controllerOld}/{actionOld}/{idOld}",
   new { controller = "Redirect", action = "Permanent", id = UrlParameter.Optional }
);
routes.MapRoute(
   "OldEx",
   "{controllerOld}/{actionOld}/{idOld}/{titleOld}",
   new { controller = "Redirect", action = "Permanent", id = UrlParameter.Optional, title = UrlParameter.Optional }
);

然後編寫一個執行重定向的控制器類:

public class RedirectController : Controller
{
   public ActionResult Permanent(string controllerOld, string actionOld, string idOld, string titleOld)
   {
       return RedirectToRoutePermanent(new {
           lang = "en",
           controller = controllerOld,
           action = actionOld,
           id = idOld,
           title = titleOld
       });
   }
}

解決方案二——IIS URL重寫模組

此解決方案依賴於 IIS URL 重寫模組,您可以在其中將任何請求重寫為您喜歡的預設語言,而無需選擇語言。

我不打算在這裡寫 URL 重寫是如何工作的,因為有大量的網路資源提供了詳細的資訊。

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