如何在 MVC 選擇路由之前添加路由參數
我正在嘗試向現有的 MVC 3 應用程序添加對不同語言的支持。到目前為止,我的連結是
oldUrl -> myapp.com/Item/Details/5/some-title並且有來自網路上不同地方的網站連結。但現在我想更改 URL,以便包含語言:
newUrl -> kmyapp.com/en/Item/Details/5/some-title但是我希望 oldUrl 連結有效。問題是我該怎麼做……最簡單的方法是添加另一條路線,但我已經有太多路線了,而且它變得有點難看,當我從一個沒有的頁面創建網址時有語言連結也沒有語言,所以我必須做其他事情。
另一種方法是覆蓋在 MVC 嘗試將請求映射到特定路由之前存在的內容,但已經解析了請求 url 並填充了 routeValues 字典。所以我可以只檢查語言,如果它不包含在路由參數中,我可以自己添加它並呼叫父類的實現以繼續。那可能嗎?我應該看什麼 - UrlRoutingModule、MvcHttpHandler或其他什麼?我可以覆蓋什麼以及如何告訴 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 重寫是如何工作的,因為有大量的網路資源提供了詳細的資訊。