148 votos

¿Atributo DisplayName de recursos?

Tengo una aplicación localizada, y me pregunto si es posible tener el nombre de visualización para un determinado modelo de 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, ya que el compilador dice: "Un atributo argumento deberá ser una expresión constante, typeof de expresión o de la creación de la matriz de expresión de un atributo de tipo de parámetro" :(

¿Hay soluciones? Estoy generar etiquetas de forma manual, pero tengo estos para el validador de salida!

357voto

René Puntos 4134

Si utiliza MVC 3 y .NET 4, puede utilizar la nueva Pantalla de atributo en el Sistema.ComponentModel.DataAnnotations espacio de nombres. Este atributo reemplaza el atributo DisplayName y proporciona mucha más funcionalidad, incluyendo soporte de localización.

En su caso, usarla como este:

public class MyModel
{
    [Required]
    [Display(Name = "labelForName", ResourceType = typeof(Resources.Resources))]
    public string name{ get; set; }
}

Como una nota del lado, este atributo no funcionará con los recursos dentro de App_GlobalResources o App_LocalResources. Esto tiene que ver con la herramienta personalizada (GlobalResourceProxyGenerator) estos utilización de los recursos. En lugar asegúrese de que su archivo de recursos se establece para 'recurso Incrustado' y el uso de la 'ResXFileCodeGenerator' herramienta personalizada.

(Más una nota de lado, usted no debería estar usando App_GlobalResources o App_LocalResources con MVC. Usted puede leer más acerca de por qué este es el caso aquí)

101voto

Darin Dimitrov Puntos 528142

¿Por qué 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 podían ser utilizados como esto:

public class MyModel 
{
    [Required]
    [LocalizedDisplayName("labelForName")]
    public string Name { get; set; }
}

20voto

Wahid Bitar Puntos 3482

Actualización:

Sé que es demasiado tarde, pero me gustaría agregar esta actualización:

Estoy utilizando el Modelo Convencional de Metadatos Proveedor que presentó por Phil Haacked es más potente y fácil de aplicar tomar un vistazo : ConventionalModelMetadataProvider


Respuesta Anterior

Aquí si quieres apoyar a 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);
        }
    }
}

Luego usarlo como este:

    [LocalizedDisplayName("Password", typeof(Res.Model.Shared.ModelProperties))]
    public string Password { get; set; }

Para la localización completa tutorial ver esta página.

11voto

Magnus Karlsson Puntos 777

Tengo respuesta Gunders trabajando con mi App_GlobalResources eligiendo las propiedades de recursos y cambiar la "Herramienta personalizada" a "PublicResXFileCodeGenerator" construir acciones para "Recurso incrustado". Por favor observe Gunders comentar abajo.

enter image description here

Funciona como un encanto :)

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X