我正在制定一个新项目的概念,我需要支持多语言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