Estoy trabajando con un cliente que quiere que las URL en nuestra aplicación web estén en francés. Soy un desarrollador inglés y también tenemos clientes ingleses. Este es un problema interesante, pero no creo que sea algo que el ASP.NET MVC Framework pueda soportar.¿Es posible localizar una URL/enrutamiento en ASP.NET MVC?
Aquí está el escenario. La ruta ...
ejemplo específico
Inglés URL
www.stackoverflow.com/questions/ask
también apoyaría
francesa URL
www.stackoverflow.com/problème/poser
Genérico EJEMPLO
Inglés URL
http://clientA.product.com/AreaNameEnglish/ControllerNameEnglish/ActionNameEnglish/params
también tiene que apoyar
URL francesa
http://clientB.product.com/AreaNameFrench/ControllerNameFrench/ActionNameFrench/params
Así que en mi área MVC, controlador, y acciones todos tenemos que tener tanto traducciones Inglés y Francés.
Obviamente, la capacidad de mantenimiento sería un ENORME problema si tuviera que codificar todos mis controladores, vistas y nombres de acción en francés. ¿Hay alguna forma de localizar la ruta que se presenta en el navegador sin hacer esto? Teniendo en cuenta que hay muchas rutas diferentes en la aplicación. Un par de áreas, cada una con un puñado de controladores, cada uno con muchas acciones.
Gracias,
Justin
EDITAR
Gracias a @womp aquí es lo que he encontrado hasta el momento ... Aunque al final tomé el enfoque que he publicado como respuesta .
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;
}
}
A decent start. Si localizo solo ControllerName y ActionName en la URL, encontrará y mostrará la Vista correcta. Sin embargo, tengo los siguientes problemas.
Nombre del área, no se puede traducir
La localización de la Zona significa el método Controller.View() no encuentra Vistas. Aunque he reemplazado el nombre del Área en el contexto de la solicitud, el método ViewEngineCollection.Find() no parece recogerlo. En cualquier parte de mi clase Controller que devuelva "View()" no puede encontrar la vista predeterminada para su acción. Si no localizo el Área entonces los otros pasos funcionan.
RedirectToAction o Html.ActionLink
Cada vez que la aplicación llama RedirectToAction o si uso un ayudante Html.ActionLink o algo similar generan las URL son las inglesas. Parece que tendré que agregar lógica en algún lugar posiblemente en varios lugares para convertir una URL en inglés a la francesa (u otro idioma).
Buen hallazgo. Es esencialmente el mismo concepto, excepto encapsulado en el enrutamiento, en lugar de en la lógica de creación de instancias del controlador. Estoy de acuerdo, es probable que sea un poco más elegante, parece ser un dominio más apropiado para la solución. – womp
Sé que esta es una publicación anterior, pero ustedes simplemente me salvan la piel. ¡Gran respuesta! –