我正在和一位希望我们的Web应用程序中的URL使用法语的客户端合作。我是英语开发人员,我们也有英语客户。这是一个有趣的问题,但我不认为它是ASP.NET MVC框架支持的东西。是否可以在ASP.NET MVC中本地化URL /路由?
这里是场景。路线...
具体的例子
英文网址
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()方法似乎没有提取它。在执行“返回View()”的Controller类中的任何位置都无法找到其操作的默认视图。如果我没有将区域本地化,那么其他步骤就可以工作。
RedirectToAction或Html.ActionLink
每当应用程序调用RedirectToAction或者如果我使用的Html.ActionLink辅助或类似的东西的URL生成是英文的。看起来我必须在多个地方添加逻辑,以将英文网址转换为法文(或其他语言)。
很好找。它基本上是相同的概念,除了封装在路由中,而不是在控制器实例化逻辑中。我同意,它可能更优雅一些,它似乎是解决方案的更合适的领域。 – womp 2010-10-15 02:40:57
我知道这是一个旧帖子,但你们只是救了我的皮肤。很好的答案! – 2014-10-14 18:12:51