public class Class1
{
[DisplayName("Something To Name")]
public virtual string Name { get; set; }
}
How to get the value of DisplayName attribute in C# ?
public class Class1
{
[DisplayName("Something To Name")]
public virtual string Name { get; set; }
}
How to get the value of DisplayName attribute in C# ?
Try these utility methods of mine:
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;
}
Usage would be:
string displayName = ReflectionExtensions.GetPropertyDisplayName<SomeClass>(i => i.SomeProperty);
First off, you need to get a MemberInfo
object that represents that property. You will need to do some form of reflection:
MemberInfo property = typeof(Class1).GetProperty("Name");
(I'm using "old-style" reflection, but you can also use an expression tree if you have access to the type at compile-time)
Then you can fetch the attribute and obtain the value of the DisplayName
property:
var attribute = property.GetCustomAttributes(typeof(DisplayNameAttribute), true)
.Cast<DisplayNameAttribute>().Single();
string displayName = attribute.DisplayName;
() parentheses are required typo error
You need to get the PropertyInfo
associated with the property (e.g. via typeof(Class1).GetProperty("Name")
) and then call GetCustomAttributes
.
It's a bit messy due to returning multiple values - you may well want to write a helper method to do this if you need it from a few places. (There may already be a helper method in the framework somewhere, but if there is I'm unaware of it.)
EDIT: As leppie pointed out, there is such a method: Attribute.GetCustomAttribute(MemberInfo, Type)
Attribute.GetCustomAttribute(MemberInfo, Type)
:) msdn.microsoft.com/en-us/library/ms130863 –
Untuck If anyone is interested in getting the localized string from the property with DisplayAttribute and ResourceType like this:
[Display(Name = "Year", ResourceType = typeof(ArrivalsResource))]
public int Year { get; set; }
Use the following after displayAttribute != null
(as shown above by @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();
DisplayAttribute
has GetName
method. No need for your code in .NET 4+ : msdn.microsoft.com/en-us/library/… –
Apprise GetName()
method just returns the Key, and not the Value specified in the resources file. –
Impede .GetName()
instead of the code above, see the problem I had with the code above here : #43827860 –
Shielashield var propInfo = typeof(Class1).GetProperty("Name");
var displayNameAttribute = propInfo.GetCustomAttributes(typeof(DisplayNameAttribute), false);
var displayName = (displayNameAttribute[0] as DisplayNameAttribute).DisplayName;
displayName
variable now holds the property's value.
From within a view that has Class1 as it's strongly typed view model:
ModelMetadata.FromLambdaExpression<Class1, string>(x => x.Name, ViewData).DisplayName;
Nice classes by Rich Tebb! I've been using DisplayAttribute and the code did not work for me. The only thing I've added is handling of DisplayAttribute. Brief search yielded that this attribute is new to MVC3 & .Net 4 and does almost the same thing plus more. Here's a modified version of the method:
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;
}
}
}
I have this generic utility method. I pass in a list of a given type (Assuming you have a supporting class) and it generates a datatable with the properties as column headers and the list items as data.
Just like in standard MVC, if you dont have DisplayName attribute defined, it will fall back to the property name so you only have to include DisplayName where it is different to the property name.
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;
}
If there's a more efficient / safer way of doing this, I'd appreicate any feedback. The commented //Where clause will filter out virtual properties. Useful if you are using model classes directly as EF puts in "Navigation" properties as virtual. However it will also filter out any of your own virtual properties if you choose to extend such classes. For this reason, I prefer to make a ViewModel and decorate it with only the needed properties and display name attributes as required, then make a list of them.
Hope this helps.
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(foo);
foreach (PropertyDescriptor property in properties)
{
if (property.Name == "Name")
{
Console.WriteLine(property.DisplayName); // Something To Name
}
}
where foo
is an instance of Class1
Assuming property
as PropertyInfo
type, you can do this in one single line:
property.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast<DisplayNameAttribute>().Single().DisplayName
Late to the party I know.
I use this:
public static string GetPropertyDisplayName(PropertyInfo pi)
{
var dp = pi.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast<DisplayNameAttribute>().SingleOrDefault();
return dp != null ? dp.DisplayName : pi.Name;
}
Hope this helps.
Try this code:
EnumEntity.item.GetType().GetFields()[(int)EnumEntity.item].CustomAttributes.ToArray()[0].NamedArguments[0].TypedValue.ToString()
It will give you the value of data attribute Name
.
This works, thanks to someone above:
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;
}
}
if you're here for [Display(Name="")] below code might help:
var props = yourObject.GetType().GetProperties();
foreach (var item in props)
{
string title = item.GetCustomAttributes(typeof(DisplayAttribute), true).Cast<DisplayAttribute>().SingleOrDefault()?.Name;
}
PropertyInfo[] properties = typeof(T).GetProperties();
String displayName = null;
foreach (PropertyInfo pi in properties){
var displayAttribute = pi.GetCustomAttribute(typeof(DisplayAttribute));
if (displayAttribute != null)
{
displayName = (displayAttribute as DisplayAttribute).GetName();
}
}
Following Rich Tebb's and Matt Baker's answer, I wanted to use the ReflectionExtensions
methods in a LINQ query, but it didn't work, so I've made this method for it to work.
If DisplayNameAttribute
is set the method will return it, otherwise it will return the MemberInfo
name.
Test method:
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)));
}
Test method output:
The class with DisplayName1
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; }
}
And the extension method:
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;
}
GetPropertyInformation()
does not exist in this context. I've just realised that this code is present in an answer below –
Giacopo Please try below code, I think this will solve your problem.
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);
}
If instead
[DisplayName("Something To Name")]
you use
[Display(Name = "Something To Name")]
Just do this:
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;
}
This code worked for me...
Class definition:
using System.ComponentModel.DataAnnotations;
public class Class1{
[Display(Name = "Something To Name")]
public string PropertyOfMyClass1{ get; set; }
}
in your own method:
using System.Web.Mvc;
string displayName = ModelMetadata.FromLambdaExpression(x => x.PropertyOfMyClass1, new ViewDataDictionary<Class1>()).DisplayName;
Result:
displayName --> "Something To Name"
in your code change PropertyOfMyClass1
and Class1
with your own values.
© 2022 - 2024 — McMap. All rights reserved.