我正在制定一個新項目的概念,我需要支持多語言URL。理想情況下,所有URL都需要使用用戶的本地語言。所以,我們不希望使用domain.com/en/contact和domain.com/es/contact但我們喜歡domain.com/contact和domain.com/contactar(contactar是西班牙語聯繫)。內部兩者應該路由到相同的ContactController類。使用ASP.NET MVC的多語言網址
這可以通過爲每種語言向Global.asax.cs添加多條靜態路由來處理,但我們希望使其變得非常動態,並希望系統的用戶能夠更改URL的翻譯通過內容管理系統。所以我們需要一些從URL到控制器和動作的動態映射。
通過查看MVC3的源代碼我想通了MvcHandler的ProcessRequestInit方法是負責確定創建哪個控制器。它僅查找RouteData以獲取控制器的名稱。覆蓋默認MVC路由的一種方法是創建一個簡單的默認路由,使用自定義RouteHandler。 This RouteHandler強制MVC使用我自己的定製子版本MvcHandler,它覆蓋了ProcessRequestInit方法。此重寫方法將我自己的動態找到的控制器和操作插入RouteData,然後再調用回原始ProcessRequestInit。
我已經試過這樣:
的Global.asax.cs
routes.Add(
new Route("{*url}", new MultilingualRouteHandler())
{
Defaults = new RouteValueDictionary(new { controller = "Default", action = "Default" })
}
);
MultilingualRouteHandler.cs
public class MultilingualRouteHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new MultilingualMVCHandler(requestContext);
}
}
MultilingualMvcHandler.cs
public class MultilingualMVCHandler : MvcHandler
{
public MultilingualMVCHandler(RequestContext context) : base(context)
{
}
protected override void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory)
{
if (RequestContext.RouteData.Values.ContainsKey("controller"))
{
RequestContext.RouteData.Values.Remove("controller");
}
if (RequestContext.RouteData.Values.ContainsKey("action"))
{
RequestContext.RouteData.Values.Remove("action");
}
RequestContext.RouteData.Values.Add("controller", "Product");
RequestContext.RouteData.Values.Add("action", "Index");
base.ProcessRequestInit(httpContext, out controller, out factory);
}
}
在這個處理程序中,我將控制器和操作硬編碼爲測試目的的固定值,但要實現這種動態並不困難。它的工作原理,但唯一的問題是,我不得不修改ASP.NET MVC3的源代碼以使其工作。問題是ProcessRequestInit方法MvcHandler是私有的,因此不能被覆蓋。我修改了源代碼並將其更改爲受保護的虛擬,這使我可以覆蓋它。
這是偉大的,但可能不是最好的解決方案。我總是需要分發我自己版本的System.Web.Mvc.dll,這很麻煩。它會好得多,它會與RTM版本一起工作。
我是否缺少任何其他可能性掛鉤到ASP.NET MVC,這將允許我動態地確定控制器和要啓動的操作,具體取決於URL?我想到的另一種方式是在* Application_Start *上動態創建RouteCollection,但我認爲這會讓它在運行中更改變得更加困難。
我會很感激我還沒有找到的鉤子的任何提示。
看起來像一個很好的解決方案,可能工作一樣好或比實際的IRouteHandler或Conroller實現更好......我現在要玩它:) – bbqchickenrobot 2011-06-24 21:55:16