netcore net mvc multilenguaje istringlocalizer asp and c# asp.net-mvc localization resources resx

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))] }

  1. Defina ResourceType del atributo para que busque un recurso
  2. Defina el nombre del atributo que se utiliza para la clave del recurso, después de C # 6.0, puede usar el nameof de la nameof fuerte nameof en lugar de la codificación nameof de la clave.

  3. Establezca la cultura de la secuencia actual en el controlador.

Resource.Culture = CultureInfo.GetCultureInfo("zh-CN");

  1. Establecer el acceso del recurso a público

  2. Muestra la etiqueta en cshtml como esta

@Html.DisplayNameFor(model => model.Age)