route - Localización en ASP.NET MVC 4 utilizando App_GlobalResources
tag helper asp net core 2 (2)
Estoy tratando de lograr dos cosas:
- Localice los mensajes de error "incorporados" para "FieldMustBeDate" y "FieldMustBeNumeric".
- Localice algunos de los otros mensajes de error que encontrará, por ejemplo, "PropertyValueRequired".
Al usar http://forums.asp.net/t/1862672.aspx/1 para el problema 1 y MVC 4 ignora DefaultModelBinder.ResourceClassKey para el problema 2, he logrado que ambos trabajen localmente.
Sin embargo, tan pronto como publico en un sitio web, los mensajes de error "incorporados" vuelven a los valores predeterminados en inglés mientras que los otros mensajes de error permanecen localizados.
He leído varios lugares que deberían evitarse al usar App_GlobalResources, pero no puedo resolver el problema 1 sin usarlo.
Creé un archivo .resx con el nombre "WebResources.resx", establecí la Acción de compilación en "Embebido", establecí el directorio Copiar a salida en "No copiar", configuré la herramienta personalizada en "PublicResXFileCodeGenerator" y configuré el Custom Tool Namespace a "Recursos". El proyecto en sí está configurado para publicar solo los archivos que se necesitan.
Mi Global.asax.cs contiene el siguiente código (relevante):
ClientDataTypeModelValidatorProvider.ResourceClassKey = "WebResources";
DataAnnotationsModelValidatorProvider.RegisterAdapter(
typeof(RequiredAttribute),
typeof(MyRequiredAttributeAdapter));
Y la clase MyRequiredAttributeAdapter contiene el siguiente código:
public class MyRequiredAttributeAdapter : RequiredAttributeAdapter
{
public MyRequiredAttributeAdapter(
ModelMetadata metadata,
ControllerContext context,
RequiredAttribute attribute
)
: base(metadata, context, attribute)
{
if (attribute.ErrorMessageResourceType == null)
{
attribute.ErrorMessageResourceType = typeof(Resources.WebResources);
}
if (attribute.ErrorMessageResourceName == null)
{
attribute.ErrorMessageResourceName = "PropertyValueRequired";
}
}
}
Esto funciona a nivel local, sin embargo, ¿alguien tiene alguna idea sobre cómo hacer que los mensajes "integrados" funcionen después de que se publique?
¡Gracias por tu ayuda!
Saludos cordiales, Andreas
He hecho algunas adiciones menores a la publicación original, que no tradujo todos los mensajes en mi caso. (Longitud de cadena y valores de propiedad no válidos)
Siga los pasos anteriores para crear los archivos * .resx, establezca sus propiedades y luego configure la configuración regional en web.config, tal como lo describe Andreas.
Luego crea un par de adaptadores:
// As described in original post:
public class LocalizedRequiredAttributeAdapter : RequiredAttributeAdapter
{
public LocalizedRequiredAttributeAdapter(
ModelMetadata metadata,
ControllerContext context,
RequiredAttribute attribute
)
: base(metadata, context, attribute)
{
if (attribute.ErrorMessageResourceType == null)
attribute.ErrorMessageResourceType = typeof(Resources.Resources);
if (attribute.ErrorMessageResourceName == null)
attribute.ErrorMessageResourceName = "PropertyValueRequired";
}
}
// Addition to original post:
public class LocalizedStringLengthAttributeAdapter : StringLengthAttributeAdapter
{
public LocalizedStringLengthAttributeAdapter(
ModelMetadata metadata,
ControllerContext context,
StringLengthAttribute attribute
)
: base(metadata, context, attribute)
{
if (attribute.ErrorMessageResourceType == null)
attribute.ErrorMessageResourceType = typeof(Resources.Resources);
if (attribute.ErrorMessageResourceName == null)
attribute.ErrorMessageResourceName = "StringLengthAttribute_ValidationError";
}
}
Y en Global.asax.cx:
// Addition to original post: (Used for "PropertyValueInvalid")
DefaultModelBinder.ResourceClassKey = "Resources";
// As described in original post:
ClientDataTypeModelValidatorProvider.ResourceClassKey = "Resources";
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RequiredAttribute), typeof(LocalizedRequiredAttributeAdapter));
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(StringLengthAttribute), typeof(LocalizedStringLengthAttributeAdapter));
Me di cuenta de esto yo mismo. Si está tratando de lograr lo anterior, debe separar los mensajes de error localizados.
Cree un archivo * .resx para los otros mensajes de error fx "PropertyValueRequired" y configure Build Action en "Embedded", establezca Copy to Output Directory en "Do not Copy", configure Custom Tool en "PublicResXFileCodeGenerator" y establezca Custom. Tool Namespace a "Recursos".
En mi caso, he movido "PropertyValueRequired" a un archivo llamado LocalDanish.resx (todavía en la carpeta App_GlobalResources) y he cambiado la línea en mi "MyRequiredAttributeAdapter" de
attribute.ErrorMessageResourceType = typeof(Resources.WebResources);
a
attribute.ErrorMessageResourceType = typeof(Resources.LocalDanish);
Para que funcionen los mensajes de error "integrados", debe crear dos archivos * .resx. Creé WebResources.resx y WebResources.da.resx. NO cambie nada, deje la configuración en ellos predeterminada (Acción de compilación en "Contenido", etc.). Supongo que el sitio web busca automáticamente los archivos * .da.resx en mi caso porque he configurado la globalización en mi WebConfig:
<globalization uiCulture="da-DK" culture="da-DK"/>
Espero que esto ayude a cualquiera.
Saludos cordiales, Andreas