我正在与一个客户合作,该客户希望我们Web应用程序中的URL为法语。 我是一名英语开发人员,我们还有英语客户。 这是一个有趣的问题,但我不认为ASP.NET MVC框架支持这种功能。
以下是具体情况...
特定示例
英语URL
www.stackoverflow.com/questions/ask
还应当支持
法语URL
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中,我的区域(Area)、控制器(Controller)和操作(Actions)都需要有英文和法文翻译。
显然,如果我要将所有控制器、视图和操作名称硬编码成法语,那么可维护性将成为一个巨大的问题。有没有办法本地化在浏览器中呈现的路由而不需要这样做?要记住,应用程序中有许多不同的路由。 一些区域每个都有几个控制器,每个控制器都有许多操作?
谢谢,
Justin
编辑
感谢@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,则可以找到并呈现正确的视图。但是我遇到了以下问题。
无法翻译区域名称
本地化区域意味着Controller.View()方法无法找到视图。
尽管我已经在请求上下文中替换了Area名称,但ViewEngineCollection.Find()方法似乎没有使用它。我的任何控制器类中执行“return View()”的位置都无法找到其操作的默认视图。如果我不本地化Area,则其他步骤将正常工作。
RedirectToAction或Html.ActionLink
每当应用程序调用RedirectToAction或者我使用Html.ActionLink助手或类似的内容时,生成的Url都是英文的。看起来我需要在某个地方添加逻辑,可能会在多个位置将英文Url转换为法语(或其他语言)。