obtener el valor del atributo DisplayName

public class Class1 { [DisplayName("Something To Name")] public virtual string Name { get; set; } } 

¿Cómo obtener el valor del atributo DisplayName en C #?

Prueba estos métodos de utilidad míos:

 using System.ComponentModel; using System.Globalization; using System.Linq; public static T GetAttribute(this MemberInfo member, bool isRequired) where T : Attribute { var attribute = member.GetCustomAttributes(typeof(T), false).SingleOrDefault(); if (attribute == null && isRequired) { throw new ArgumentException( string.Format( CultureInfo.InvariantCulture, "The {0} attribute must be defined on member {1}", typeof(T).Name, member.Name)); } return (T)attribute; } public static string GetPropertyDisplayName(Expression> propertyExpression) { var memberInfo = GetPropertyInformation(propertyExpression.Body); if (memberInfo == null) { throw new ArgumentException( "No property reference expression was found.", "propertyExpression"); } var attr = memberInfo.GetAttribute(false); if (attr == null) { return memberInfo.Name; } return attr.DisplayName; } public static MemberInfo GetPropertyInformation(Expression propertyExpression) { Debug.Assert(propertyExpression != null, "propertyExpression != null"); MemberExpression memberExpr = propertyExpression as MemberExpression; if (memberExpr == null) { UnaryExpression unaryExpr = propertyExpression as UnaryExpression; if (unaryExpr != null && unaryExpr.NodeType == ExpressionType.Convert) { memberExpr = unaryExpr.Operand as MemberExpression; } } if (memberExpr != null && memberExpr.Member.MemberType == MemberTypes.Property) { return memberExpr.Member; } return null; } 

El uso sería:

 string displayName = ReflectionExtensions.GetPropertyDisplayName(i => i.SomeProperty); 

Necesita obtener PropertyInfo asociado con la propiedad (por ejemplo, a través de typeof(Class1).GetProperty("Name") ) y luego llamar a GetCustomAttributes .

Es un poco desordenado debido a la devolución de valores múltiples; es posible que desee escribir un método de ayuda para hacerlo si lo necesita desde algunos lugares. (Puede que ya exista un método de ayuda en el marco en alguna parte, pero si lo hay, no lo sé).

EDITAR: Como señaló Leppie, existe dicho método: Attribute.GetCustomAttribute(MemberInfo, Type)

En primer lugar, debe obtener un objeto MemberInfo que represente esa propiedad. Necesitarás hacer alguna forma de reflexión:

 MemberInfo property = typeof(Class1).GetProperty("Name"); 

(Estoy usando el reflection “antiguo”, pero también puedes usar un árbol de expresiones si tienes acceso al tipo en tiempo de comstackción)

Luego puede buscar el atributo y obtener el valor de la propiedad DisplayName :

 var attribute = property.GetCustomAttributes(typeof(DisplayNameAttribute), true) .Cast().Single(); string displayName = attribute.DisplayName; 

() paréntesis son necesarios error tipográfico

Si alguien está interesado en obtener la cadena localizada de la propiedad con DisplayAttribute y ResourceType de esta manera:

 [Display(Name = "Year", ResourceType = typeof(ArrivalsResource))] public int Year { get; set; } 

Utilice lo siguiente después de displayAttribute != null Null (como se muestra arriba por @alex ‘respuesta ):

 ResourceManager resourceManager = new ResourceManager(displayAttribute.ResourceType); var entry = resourceManager.GetResourceSet(Thread.CurrentThread.CurrentUICulture, true, true) .OfType() .FirstOrDefault(p => p.Key.ToString() == displayAttribute.Name); return entry.Value.ToString(); 

Desde dentro de una vista que tiene Class1, ya que está fuertemente tipada, ve el modelo:

 ModelMetadata.FromLambdaExpression(x => x.Name, ViewData).DisplayName; 

Buenas clases por Rich Tebb! He estado usando DisplayAttribute y el código no funcionó para mí. Lo único que agregué es el manejo de DisplayAttribute. Una breve búsqueda arrojó que este atributo es nuevo en MVC3 y .Net 4 y hace casi lo mismo y más. Aquí hay una versión modificada del método:

  public static string GetPropertyDisplayString(Expression> propertyExpression) { var memberInfo = GetPropertyInformation(propertyExpression.Body); if (memberInfo == null) { throw new ArgumentException( "No property reference expression was found.", "propertyExpression"); } var displayAttribute = memberInfo.GetAttribute(false); if (displayAttribute != null) { return displayAttribute.Name; } else { var displayNameAttribute = memberInfo.GetAttribute(false); if (displayNameAttribute != null) { return displayNameAttribute.DisplayName; } else { return memberInfo.Name; } } } 
  PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(foo); foreach (PropertyDescriptor property in properties) { if (property.Name == "Name") { Console.WriteLine(property.DisplayName); //Something To Name } } 

donde foo es una instancia de Class1

Tengo este método de utilidad genérico. Paso en una lista de un tipo dado (suponiendo que tenga una clase de soporte) y genera una tabla de datos con las propiedades como encabezados de columna y los elementos de la lista como datos.

Al igual que en MVC estándar, si no tiene definido el atributo DisplayName, volverá al nombre de la propiedad, por lo que solo debe incluir DisplayName, que es diferente del nombre de la propiedad.

  public DataTable BuildDataTable(IList data) { //Get properties PropertyInfo[] Props = typeof(T).GetProperties(BindingFlags.Public | BindingFlags.Instance); //.Where(p => !p.GetGetMethod().IsVirtual && !p.GetGetMethod().IsFinal).ToArray(); //Hides virtual properties //Get column headers bool isDisplayNameAttributeDefined = false; string[] headers = new string[Props.Length]; int colCount = 0; foreach (PropertyInfo prop in Props) { isDisplayNameAttributeDefined = Attribute.IsDefined(prop, typeof(DisplayNameAttribute)); if (isDisplayNameAttributeDefined) { DisplayNameAttribute dna = (DisplayNameAttribute)Attribute.GetCustomAttribute(prop, typeof(DisplayNameAttribute)); if (dna != null) headers[colCount] = dna.DisplayName; } else headers[colCount] = prop.Name; colCount++; isDisplayNameAttributeDefined = false; } DataTable dataTable = new DataTable(typeof(T).Name); //Add column headers to datatable foreach (var header in headers) dataTable.Columns.Add(header); dataTable.Rows.Add(headers); //Add datalist to datatable foreach (T item in data) { object[] values = new object[Props.Length]; for (int col = 0; col < Props.Length; col++) values[col] = Props[col].GetValue(item, null); dataTable.Rows.Add(values); } return dataTable; } 

Si hay una manera más eficiente / más segura de hacer esto, agradecería cualquier comentario. La // cláusula comentada filtrará las propiedades virtuales. Es útil si está utilizando clases de modelo directamente ya que EF pone en propiedades de "Navegación" como virtuales. Sin embargo, también filtrará cualquiera de sus propias propiedades virtuales si elige extender dichas clases. Por esta razón, prefiero crear un modelo de vista y decorarlo con solo las propiedades necesarias y los atributos de nombre para mostrar según sea necesario, y luego hacer una lista de ellos.

Espero que esto ayude.

 var propInfo = new Class1().GetType().GetProperty("Name"); var displayNameAttribute = propInfo.GetCustomAttributes(typeof(DisplayNameAttribute), false); var displayName = displayNameAttribute[0] as DisplayNameAttribute).DisplayName; 

displayName variable displayName ahora contiene el valor de la propiedad.

Asumiendo property como tipo PropertyInfo , puede hacer esto en una sola línea:

 property.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast().Single().DisplayName 

Prueba este código:

 EnumEntity.item.GetType().GetFields()[(int)EnumEntity.item].CustomAttributes.ToArray()[0].NamedArguments[0].TypedValue.ToString() 

Le dará el valor del Name atributo de datos.

después de la respuesta de Rich Tebb y Matt Baker, quería usar los métodos ReflectionExtensions en una consulta de linq pero no funcionó, así que hice este método para que funcione: si DisplayNameAttribute está configurado, el método lo devolverá, de lo contrario lo hará devuelve el nombre de memberinfo:

método de prueba:

 static void Main(string[] args) { var lst = new List(); lst.Add(new Test("coucou1", "kiki1")); lst.Add(new Test("coucou2", "kiki2")); lst.Add(new Test("coucou3", "kiki3")); lst.Add(new Test("coucou4", "kiki4")); lst.ForEach(i => Console.WriteLine(i.GetAttributeName(t => t.Name)+";"+i.GetAttributeName(t=>t.t2))); } 

// resultado del método de prueba:

Salida del método de prueba

// debajo: la clase con DisplayName Attribute

 public class Test { public Test() { } public Test(string name, string T2) { Name = name; t2 = T2; } [DisplayName("toto")] public string Name { get; set; } public string t2 { get; set; } } 

// y el método de extensión:

 public static string GetAttributeName(this T itm, Expression> propertyExpression) { var memberInfo = GetPropertyInformation(propertyExpression.Body); if (memberInfo == null) { throw new ArgumentException( "No property reference expression was found.", "propertyExpression"); } var pi = typeof(T).GetProperty(memberInfo.Name); var ret = pi.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast().SingleOrDefault(); return ret != null ? ret.DisplayName : pi.Name; }