get the value of DisplayName attribute

C#Attributes

C# Problem Overview


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

How to get the value of DisplayName attribute in C# ?

C# Solutions


Solution 1 - 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);

Solution 2 - C#

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

Solution 3 - C#

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)

Solution 4 - C#

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();

Solution 5 - C#

From within a view that has Class1 as it's strongly typed view model:

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

Solution 6 - C#

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.

Solution 7 - C#

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

Solution 8 - C#

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.

Solution 9 - C#

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

Solution 10 - C#

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.

Solution 11 - C#

Assuming property as PropertyInfo type, you can do this in one single line:

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

Solution 12 - C#

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.

Solution 13 - C#

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

Solution 14 - C#

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:

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;

}

Solution 15 - C#

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

Solution 16 - C#

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

Solution 17 - C#

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

Solution 18 - C#

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionBassam BsataView Question on Stackoverflow
Solution 1 - C#Rich TebbView Answer on Stackoverflow
Solution 2 - C#R. Martinho FernandesView Answer on Stackoverflow
Solution 3 - C#Jon SkeetView Answer on Stackoverflow
Solution 4 - C#Matija GrcicView Answer on Stackoverflow
Solution 5 - C#Luke BennettView Answer on Stackoverflow
Solution 6 - C#Dishan SamarawickramaView Answer on Stackoverflow
Solution 7 - C#alexView Answer on Stackoverflow
Solution 8 - C#Francis RodgersView Answer on Stackoverflow
Solution 9 - C#FooView Answer on Stackoverflow
Solution 10 - C#Raul MarquezView Answer on Stackoverflow
Solution 11 - C#Leonel Sanches da SilvaView Answer on Stackoverflow
Solution 12 - C#RafaelView Answer on Stackoverflow
Solution 13 - C#T NewcView Answer on Stackoverflow
Solution 14 - C#XavaveView Answer on Stackoverflow
Solution 15 - C#SidView Answer on Stackoverflow
Solution 16 - C#MarchalPTView Answer on Stackoverflow
Solution 17 - C#farhang67View Answer on Stackoverflow
Solution 18 - C#simonataView Answer on Stackoverflow