Jus*_*tin 14 url asp.net-mvc localization asp.net-mvc-routing
我正在与希望我们的Web应用程序中的URL使用法语的客户端合作.我是英语开发人员,我们也有英语客户.这是一个有趣的问题,但我不认为ASP.NET MVC框架会支持它.
这是场景.路线...
具体示例
英文网址
www.stackoverflow.com/questions/ask
也会支持
法语网址
www.stackoverflow.com/problème/poser
通用示例
英文URL
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;
}
}
Run Code Online (Sandbox Code Playgroud)
一个不错的开始.如果我只在Url中本地化ControllerName和ActionName,它将找到并呈现正确的视图.但是我有以下问题.
区域名称无法转换
本地化区域意味着Controller.View()方法无法找到视图.即使我已经在请求上下文中替换了Area名称,ViewEngineCollection.Find()方法似乎也没有取出它.我的Controller类中"返回View()"的任何地方都无法找到其操作的默认视图.如果我没有本地化区域,那么其他步骤工作.
RedirectToAction或Html.ActionLink
只要应用程序调用RedirectToAction,或者如果我使用Html.ActionLink帮助程序或类似的东西,Urls生成的是英文版.看起来我将不得不在某个地方添加逻辑,以便将英语网址转换为法语(或其他语言).
Jus*_*tin 14
以下博客包含完整解决方案这个确切的问题.它实际上是一个非常优雅的解决方案,我强烈推荐
https://blog.maartenballiauw.be/post/2010/01/26/translating-routes-(aspnet-mvc-and-webforms).html
注意让它适用于AREA我必须将以下扩展方法添加到他的"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;
}
Run Code Online (Sandbox Code Playgroud)
但是,即使这样,可以读取和解释带有AREA的已转换路线,生成的路线似乎总是包含英语AREA名称,但本地化其他所有内容.
通过ASP.NET MVC 论坛上提出的相同问题,我被引导到博客
归档时间: |
|
查看次数: |
7236 次 |
最近记录: |