public class Class1
{
[DisplayName("Something To Name")]
public virtual string Name { get; set; }
}
如何在C#中获取DisplayName属性的值?
答案 0 :(得分:71)
尝试我的这些实用工具:
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);
答案 1 :(得分:29)
您需要获取与该媒体相关联的PropertyInfo
(例如,通过typeof(Class1).GetProperty("Name")
),然后拨打GetCustomAttributes
。
由于返回多个值,这有点乱 - 你可能想要编写一个帮助方法来执行此操作,如果你需要从几个地方。 (在某个框架中可能已经有一个帮助方法,但是如果我不知道它的话。)
编辑:正如leppie所指出的那样,是这样一种方法:Attribute.GetCustomAttribute(MemberInfo, Type)
答案 2 :(得分:26)
首先,你需要获得一个代表该属性的MemberInfo
对象。你需要做某种形式的反思:
MemberInfo property = typeof(Class1).GetProperty("Name");
(我正在使用“旧式”反射,但如果您在编译时可以访问该类型,也可以使用表达式树)
然后,您可以获取属性并获取DisplayName
属性的值:
var attribute = property.GetCustomAttributes(typeof(DisplayNameAttribute), true)
.Cast<DisplayNameAttribute>().Single();
string displayName = attribute.DisplayName;
()括号是必需的拼写错误
答案 3 :(得分:12)
如果有人有兴趣从 DisplayAttribute 和 ResourceType 获取属性中的本地化字符串,请执行以下操作:
[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();
答案 4 :(得分:11)
在具有Class1的视图中,因为它是强类型视图模型:
ModelMetadata.FromLambdaExpression<Class1, string>(x => x.Name, ViewData).DisplayName;
答案 5 :(得分:6)
Rich Tebb的精彩课程! 我一直在使用DisplayAttribute,代码对我不起作用。我唯一添加的是处理DisplayAttribute。简短的搜索产生了这个属性对于MVC3&amp; .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;
}
}
}
答案 6 :(得分:4)
我有这种通用的实用方法。我传入一个给定类型的列表(假设你有一个支持类),它生成一个数据表,其属性为列标题,列表项为数据。
就像在标准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放入&#34;导航&#34;属性为虚拟。但是,如果您选择扩展此类,它也会过滤掉您自己的任何虚拟属性。出于这个原因,我更喜欢创建一个ViewModel并使用所需的属性和显示名称属性来装饰它,然后列出它们。
希望这有帮助。
答案 7 :(得分:3)
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(foo);
foreach (PropertyDescriptor property in properties)
{
if (property.Name == "Name")
{
Console.WriteLine(property.DisplayName); //Something To Name
}
}
其中foo是Class1的实例
答案 8 :(得分:3)
var propInfo = new Class1().GetType().GetProperty("Name");
var displayNameAttribute = propInfo.GetCustomAttributes(typeof(DisplayNameAttribute), false);
var displayName = displayNameAttribute[0] as DisplayNameAttribute).DisplayName;
displayName
变量现在保存了该属性的值。
答案 9 :(得分:2)
迟到我认识的聚会。
我使用这个:
public static string GetPropertyDisplayName(PropertyInfo pi)
{
var dp = pi.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast<DisplayNameAttribute>().SingleOrDefault();
return dp != null ? dp.DisplayName : pi.Name;
}
希望这会有所帮助。
答案 10 :(得分:1)
假设property
为PropertyInfo
类型,您可以在一行中执行此操作:
property.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast<DisplayNameAttribute>().Single().DisplayName
答案 11 :(得分:1)
试试这段代码:
EnumEntity.item.GetType().GetFields()[(int)EnumEntity.item].CustomAttributes.ToArray()[0].NamedArguments[0].TypedValue.ToString()
它会为您提供数据属性Name
的值。
答案 12 :(得分:0)
在Rich Tebb和Matt Baker的回答之后,我想在linq查询中使用ReflectionExtensions方法,但是它没有用,所以我已经使这个方法工作了:如果设置了DisplayNameAttribute,方法将返回它,否则它将返回memberinfo名称:
测试方法:
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)));
}
//测试方法输出:
//下面:具有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;
}
答案 13 :(得分:0)
请尝试以下代码,我认为这可以解决您的问题。
var classObj = new Class1();
classObj.Name => "StackOverflow";
var property = new Class1().GetType().GetProperty(nameof(classObj.Name));
var displayNameAttributeValue = (property ?? throw new InvalidOperationException()).GetCustomAttributes(typeof(DisplayNameAttribute))as DisplayNameAttribute;
if(displayNameAttributeValue != null)
{
Console.WriteLine("{0} = {1} ",displayNameAttributeValue,classObj.Name);
}
答案 14 :(得分:0)
如果不是
[DisplayName(“要命名的东西”)]
您使用
[Display(Name =“名称的东西”)]
只需执行以下操作:
private string GetDisplayName(Class1 class1)
{
string displayName = string.Empty;
string propertyName = class1.Name.GetType().Name;
CustomAttributeData displayAttribute = class1.GetType().GetProperty(propertyName).CustomAttributes.FirstOrDefault(x => x.AttributeType.Name == "DisplayAttribute");
if (displayAttribute != null)
{
displayName = displayAttribute.NamedArguments.FirstOrDefault().TypedValue.Value;
}
return displayName;
}
答案 15 :(得分:0)
这有效,感谢上面的人:
foreach (PropertyInfo pi in properties)
{
var propName = pi.Name;
var dp = pi.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast<DisplayNameAttribute>().SingleOrDefault();
if (dp != null)
{
propName = dp.DisplayName;
}
}