获取DisplayName属性的值

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

如何获取在C#中的DisplayName属性的值?

试试我的这些实用方法:

 using System.ComponentModel; using System.Globalization; using System.Linq; public static T GetAttribute<T>(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<T>(Expression<Func<T, object>> propertyExpression) { var memberInfo = GetPropertyInformation(propertyExpression.Body); if (memberInfo == null) { throw new ArgumentException( "No property reference expression was found.", "propertyExpression"); } var attr = memberInfo.GetAttribute<DisplayNameAttribute>(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; } 

用法是:

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

您需要获取与PropertyInfo相关联的PropertyInfo(例如,通过typeof(Class1).GetProperty("Name") ),然后调用GetCustomAttributes

由于返回多个值,这有点麻烦 – 如果你需要从几个地方得到它,你可能要编写一个辅助方法来做到这一点。 (在某个框架中可能已经有了一个辅助方法,但是如果有的话我不知道)。

编辑:正如leppie指出的,有这样一个方法: Attribute.GetCustomAttribute(MemberInfo, Type)

首先,您需要获得一个表示该属性的MemberInfo对象。 你需要做一些反思:

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

(我使用的是“旧式”reflection,但是如果您可以在编译时访问该types,也可以使用expression式树)

然后,您可以获取属性并获取DisplayName属性的值:

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

()括号是必需的错字错误

在具有Class1的视图中,因为它是强types的视图模型:

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

如果有人有兴趣从DisplayAttributeResourceType属性获取本地化string,如下所示:

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

displayAttribute != null (如上面的@alex'answer所示)后使用以下内容:

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

Rich Tebb的好课堂! 我一直在使用DisplayAttribute,代码不适合我。 我唯一添加的是处理DisplayAttribute。 简单search得出这个属性是MVC3&.Net 4的新特性,并且做了几乎相同的事情加上更多。 以下是该方法的修改版本:

  public static string GetPropertyDisplayString<T>(Expression<Func<T, object>> propertyExpression) { var memberInfo = GetPropertyInformation(propertyExpression.Body); if (memberInfo == null) { throw new ArgumentException( "No property reference expression was found.", "propertyExpression"); } var displayAttribute = memberInfo.GetAttribute<DisplayAttribute>(false); if (displayAttribute != null) { return displayAttribute.Name; } else { var displayNameAttribute = memberInfo.GetAttribute<DisplayNameAttribute>(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 } } 

其中foo是Class1的一个实例

我有这个通用的实用方法。 我传入一个给定types的列表(假设你有一个支持类),它生成一个数据表,其中的属性是列标题,列表项是数据。

就像在标准MVC中一样,如果您没有定义DisplayName属性,它将回退到属性名称,所以您只需将DisplayName包含在与属性名称不同的位置即可。

  public DataTable BuildDataTable<T>(IList<T> 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; } 

如果有这样一种更高效/更安全的方式,我会提供任何反馈意见。 评论/ / Where子句将过滤出虚拟属性。 如果您直接使用模型类,则EF非常有用,因为EF将“导航”属性设置为虚拟。 但是,如果您select扩展这些类,它也会过滤掉您自己的任何虚拟属性。 出于这个原因,我更喜欢制作一个ViewModel,并根据需要只使用所需的属性和显示名称属性来装饰它,然后列出它们。

希望这可以帮助。

假设propertyPropertyInfotypes,可以在一行中完成:

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

下面的Rich Tebb和Matt Baker的回答,我想在一个linq查询中使用ReflectionExtensions方法,但它不起作用,所以我已经使这个方法工作:如果DisplayNameAttribute设置方法将返回它,否则将返回memberinfo名称:

testing方法:

 static void Main(string[] args) { var lst = new List<Test>(); 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<Test>(t => t.Name)+";"+i.GetAttributeName<Test>(t=>t.t2))); } 

//testing方法输出:

测试方法输出

//下面:具有DisplayName属性的类

 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; } } 

//和扩展方法:

 public static string GetAttributeName<T>(this T itm, Expression<Func<T, object>> 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<DisplayNameAttribute>().SingleOrDefault(); return ret != null ? ret.DisplayName : pi.Name; } 

试试这个代码:

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

它会给你数据属性Name的值。