Tez Wingfield
Tez Wingfield

Reputation: 2251

Get class DisplayName attribute value

Iv'e spent the last hour trying to get the value of a DisplayName attribute that's applied to a Class.

I find it simple enough to get the attribute values from methods and properties but I'm struggling with the class.

Could anyone help me out with this relatively small issue?

Sample below:

The Class

 [DisplayName("Opportunity")]
 public class Opportunity
 {
  // Code Omitted
 }

The Variable

var classDisplayName = typeof(T).GetCustomAttributes(typeof(DisplayNameAttribute),true).FirstOrDefault().ToString();

I have spent much time on MSDN and SO but I guess I'm missing something stupidly simple.

Either way great question for future readers too

Any help greatly appreciated!

Upvotes: 8

Views: 16118

Answers (5)

user8604852
user8604852

Reputation: 1

If you use

[DisplayName("bla")]

from

using System.ComponentModel;

then get "bla" like this

string name = ((object)myObject).GetType().GetCustomAttribute<DisplayNameAttribute>()?.DisplayName;

Or you could use

[Display(Name = "bla")]

from

using System.ComponentModel.DataAnnotations;

and then get "bla" like this

string name = ((object)myObject).GetType().GetCustomAttribute<DisplayAttribute>()?.GetName();

the cast to object is not necessary unless you're working with dynamic type object.

thus to answer the question, I think the next code would to the trick

string name = typeof(T).GetCustomAttribute<DisplayNameAttribute>()?.DisplayName;

Upvotes: 0

Ric
Ric

Reputation: 13248

using your example I got it working doing this:

 var displayName = typeof(Opportunity)
    .GetCustomAttributes(typeof(DisplayNameAttribute), true)
    .FirstOrDefault() as DisplayNameAttribute;

if (displayName != null)
    Console.WriteLine(displayName.DisplayName);

This outputted "Opportunity".

Or for the more generic way you seem to be doing it:

public static string GetDisplayName<T>()
{
    var displayName = typeof(T)
      .GetCustomAttributes(typeof(DisplayNameAttribute), true)
      .FirstOrDefault() as DisplayNameAttribute;

    if (displayName != null)
        return displayName.DisplayName;

     return "";
}

Usage:

string displayName = GetDisplayName<Opportunity>();

GetCustomAttributes() returns an object[], so you need to apply the specific cast first before accessing the required property values.

Upvotes: 14

juharr
juharr

Reputation: 32296

Instead of ToString you need to access the DisplayName property. You can do that by casting to DisplayNameAttribute.

var classDisplayName =
    ((DisplayNameAttribute)
    typeof(Opportunity)
       .GetCustomAttributes(typeof(DisplayNameAttribute), true)
       .FirstOrDefault()).DisplayName;

Upvotes: 3

hug
hug

Reputation: 1228

Some valid solutions already exist but you could also create an extension method like this:

using System.ComponentModel.DataAnnotations;
using System.Reflection;


public static class PropertyExtension
{
    public static string GetDisplayName<T>(this string property)
    {
        MemberInfo propertyInfo = typeof(T).GetProperty(property);
        var displayAttribute = propertyInfo?.GetCustomAttribute(typeof(DisplayAttribute)) as DisplayAttribute;

        return displayAttribute != null ? displayAttribute.Name : "";
    }
}

The way you use this is by providing the name of the property as a string and then the type of the class.

var propertyNameInClass = "DateCreated"; // Could be any property
// You could probably do something like nameof(myOpportunity.DateCreated)
// to keep it strongly-typed
var displayName = propertyNameInClass.GetDisplayName<Opportunity>();
if(!string.IsNullOrEmpty(displayName))
{
    // Do something
}

I think this is more dynamic and cleaner than some other solutions around. It might be a good idea to wrap it all with a try/catch statement because of it's dynamic nature.

Upvotes: 2

aeliusd
aeliusd

Reputation: 469

Try this:

var classDisplayName = ((DisplayNameAttribute)typeof(Opportunity).GetCustomAttributes(typeof(DisplayNameAttribute), true).FirstOrDefault()).DisplayName;

Console.WriteLine(classDisplayName);

Upvotes: 0

Related Questions