这是场景.路线…
具体实施例
英文网址
www.stackoverflow.com/questions/ask
也会支持
法语URL
www.stackoverflow.com/problème/poser
通用实例
英文网址
http://clientA.product.com/AreaNameEnglish/ControllerNameEnglish/ActionNameEnglish/params
也需要支持
法语URL
http://clientB.product.com/AreaNameFrench/ControllerNameFrench/ActionNameFrench/params
所以在MVC我的区域,控制器和操作都需要有英文和法文翻译.
显然,如果我要将所有我的控制器,视图和动作名称硬编码为法语,那么可维护性将是一个巨大的问题.有没有本地化浏览器中提供的路由,而不这样做?请记住,应用程序中有很多不同的路线.一对夫妇每个都有少数控制器,每个都有很多动作?
谢谢,
贾斯汀
编辑
感谢@womp这是迄今为止我已经提出的…尽管最后我采取了我发布的方式作为答案.
public class LocalizedControllerFactory : DefaultControllerFactory { public override IController CreateController(RequestContext requestContext,string controllerName) { if (string.IsNullOrEmpty(controllerName)) throw new ArgumentNullException("controllerName"); if (CultureInfo.CurrentCulture.TwoLetterISOLanguageName == "fr") { controllerName = this.ReplaceControllerName(requestContext,controllerName); this.ReplaceActionName(requestContext); this.ReplaceAreaName(requestContext); } return base.CreateController(requestContext,controllerName); } private string ReplaceControllerName(RequestContext requestContext,string controllerName) { // would use the language above to pick the propery controllerMapper. For now just have french Dictionary<string,string> controllerMapper = new Dictionary<string,string>() { {"frenchControllerA","englishControllerA"},{"frenchControllerB","englishControllerB"} }; return this.ReplaceRouteValue(requestContext,"controller",controllerMapper); } private void ReplaceAreaName(RequestContext requestContext) { // would use the language above to pick the propery areaMapper. For now just have french Dictionary<string,string> areaMapper = new Dictionary<string,string>() { {"frenchAreaX","englishAreaX"},{"frenchAreaY","englishAreaY"} }; this.ReplaceRouteValue(requestContext,"area",areaMapper); } private void ReplaceActionName(RequestContext requestContext) { // would use the language above to pick the propery actionMapper. For now just have french Dictionary<string,string> actionMapper = new Dictionary<string,string>() { {"frenchAction1","englishAction1"},{"frenchAction2","englishAction2"} }; this.ReplaceRouteValue(requestContext,"action",actionMapper); } private string ReplaceRouteValue(RequestContext requestContext,string paramName,Dictionary<string,string> translationLookup) { if (requestContext.RouteData.Values[paramName] == null) { return null; } string srcRouteValue = requestContext.RouteData.Values[paramName] as string; if (srcRouteValue != null && translationLookup.ContainsKey(srcRouteValue)) { requestContext.RouteData.Values[paramName] = translationLookup[srcRouteValue]; } return requestContext.RouteData.Values[paramName] as string; } }
一个体面的开始.如果我本地化在Url中的ControllerName和ActionName,它将会找到并呈现正确的View.但是我有以下问题.
区域名称不能翻译
本地化区域意味着Controller.View()方法无法查找视图.
尽管我已经在请求上下文中替换了区域名称,但是ViewEngineCollection.Find()方法似乎并没有被接受.我的Controller类中的“返回View()”的任何地方找不到其操作的默认视图.如果我没有本地化该区域,那么其他步骤就可以了.
RedirectToAction或Html.ActionLink
任何时候应用程序调用RedirectToAction,或者如果我使用Html.ActionLink帮助器或类似的Urls生成的东西是英文的.看起来我将不得不在多个地点添加逻辑,将英文网址转换为法语(或其他语言).
解决方法
https://blog.maartenballiauw.be/post/2010/01/26/translating-routes-(aspnet-mvc-and-webforms).html
注意让它适用于AREAs我不得不将以下扩展方法添加到他的“TranslatedRouteCollectionExtensions.cs”类中:
public static Route MapTranslatedRoute(this AreaRegistrationContext areaContext,string name,string url,object defaults,object routeValueTranslationProviders,bool setDetectedCulture) { TranslatedRoute route = new TranslatedRoute( url,new RouteValueDictionary(defaults),new RouteValueDictionary(routeValueTranslationProviders),setDetectedCulture,new MvcRouteHandler()); route.DataTokens["area"] = areaContext.AreaName; // disabling the namespace lookup fallback mechanism keeps this areas from accidentally picking up // controllers belonging to other areas bool useNamespaceFallback = (areaContext.Namespaces == null || areaContext.Namespaces.Count == 0); route.DataTokens["UseNamespaceFallback"] = useNamespaceFallback; areaContext.Routes.Add(route); return route; }
然而,即使是这样,一个具有AREA的翻译路由也可以被读取和解释,所生成的路由似乎总是包含一个英文的AREA名称,但本地化其他的一切.