c# - net - DisplayName atributo de Recursos?
net core culture (6)
Tengo una aplicación localizada, y me pregunto si es posible tener DisplayName
para un determinado conjunto de propiedades de un recurso.
Me gustaría hacer algo como esto:
public class MyModel {
[Required]
[DisplayName(Resources.Resources.labelForName)]
public string name{ get; set; }
}
Pero no puedo hacerlo, como dice el compilador: "Un argumento de atributo debe ser una expresión constante, tipo de expresión o expresión de creación de matriz de un tipo de parámetro de atributo" :(
¿Hay alguna solución? Estoy sacando etiquetas manualmente, pero las necesito para la salida del validador.
Actualizar:
Sé que es demasiado tarde, pero me gustaría agregar esta actualización:
Estoy usando el Proveedor de Metadatos del Modelo Convencional presentado por Phil Haacked , es más potente y fácil de aplicar. Míralo : ConventionalModelMetadataProvider
Vieja respuesta
Aquí si quieres admitir muchos tipos de recursos:
public class LocalizedDisplayNameAttribute : DisplayNameAttribute
{
private readonly PropertyInfo nameProperty;
public LocalizedDisplayNameAttribute(string displayNameKey, Type resourceType = null)
: base(displayNameKey)
{
if (resourceType != null)
{
nameProperty = resourceType.GetProperty(base.DisplayName,
BindingFlags.Static | BindingFlags.Public);
}
}
public override string DisplayName
{
get
{
if (nameProperty == null)
{
return base.DisplayName;
}
return (string)nameProperty.GetValue(nameProperty.DeclaringType, null);
}
}
}
Entonces úsalo así:
[LocalizedDisplayName("Password", typeof(Res.Model.Shared.ModelProperties))]
public string Password { get; set; }
Para ver el tutorial completo de localización, vea esta página .
¿Qué le parece escribir un atributo personalizado?
public class LocalizedDisplayNameAttribute: DisplayNameAttribute
{
public LocalizedDisplayNameAttribute(string resourceId)
: base(GetMessageFromResource(resourceId))
{ }
private static string GetMessageFromResource(string resourceId)
{
// TODO: Return the string from the resource file
}
}
que podría usarse así:
public class MyModel
{
[Required]
[LocalizedDisplayName("labelForName")]
public string Name { get; set; }
}
Obtuve la respuesta de Gunders trabajando con mis App_GlobalResources al elegir las propiedades de los recursos y cambiar "Custom Tool" a "PublicResXFileCodeGenerator" y crear una acción para "Embedded Resource". Por favor, observe Gunders comentar a continuación.
Funciona de maravilla :)
Si abre su archivo de recursos y cambia el modificador de acceso a público o interno, generará una clase de su archivo de recursos que le permite crear referencias de recursos fuertemente tipadas.
Lo que significa que puede hacer algo como esto en su lugar (usando C # 6.0). Entonces no tienes que recordar si firstname fue en minúscula o en camelcased. Y puede ver si otras propiedades usan el mismo valor de recurso con a buscar todas las referencias.
[Display(Name = nameof(PropertyNames.FirstName), ResourceType = typeof(PropertyNames))]
public string FirstName { get; set; }
Si usa MVC 3 y .NET 4, puede usar el nuevo atributo Display
en el espacio de nombres System.ComponentModel.DataAnnotations
. Este atributo reemplaza el atributo DisplayName
y proporciona mucha más funcionalidad, incluido el soporte de localización.
En tu caso, lo usarías así:
public class MyModel
{
[Required]
[Display(Name = "labelForName", ResourceType = typeof(Resources.Resources))]
public string name{ get; set; }
}
Como nota al margen, este atributo no funcionará con recursos dentro de App_GlobalResources
o App_LocalResources
. Esto tiene que ver con la herramienta personalizada ( GlobalResourceProxyGenerator
) que utilizan estos recursos. En su lugar, asegúrese de que su archivo de recursos esté configurado en ''Recurso incrustado'' y use la herramienta personalizada ''ResXFileCodeGenerator''.
(Como nota al margen, no debería usar App_GlobalResources
o App_LocalResources
con MVC. Puede leer más acerca de por qué este es el caso here )
public class Person
{
// Before C# 6.0
[Display(Name = "Age", ResourceType = typeof(Testi18n.Resource))]
public string Age { get; set; }
// After C# 6.0
// [Display(Name = nameof(Resource.Age), ResourceType = typeof(Resource))]
}
- Defina ResourceType del atributo para que busque un recurso
Defina el nombre del atributo que se utiliza para la clave del recurso, después de C # 6.0, puede usar el
nameof
de lanameof
fuertenameof
en lugar de la codificaciónnameof
de la clave.Establezca la cultura de la secuencia actual en el controlador.
Resource.Culture = CultureInfo.GetCultureInfo("zh-CN");
Establecer el acceso del recurso a público
Muestra la etiqueta en cshtml como esta
@Html.DisplayNameFor(model => model.Age)