2

I'm using asp.net MVC 5 with EntityFramework 6 DataAnnotations. I would like to know if there is a way to get all DisplayName of an object and save them in a variable into a Controller class.

For example, considering the class:

public class Class1
{
    [DisplayName("The ID number")]
    public int Id { get; set; }

    [DisplayName("My Value")]
    public int Value { get; set; }

    [DisplayName("Label name to display")]
    public string Label { get; set; }
}

How to get the values of DisplayName for all attributes? For example how to create a function that returns a Dictionary< string,string > which has a key with attribute name and value with DisplayName, like this:

{ "Id": "The ID name", "Value": "My Value", "Label": "Label name to display"}.

I have seen this topic stackoverflow - get the value of DisplayName attribute but I have no ideas of a way to extends this code.

Ali
  • 3,373
  • 5
  • 42
  • 54
Cyr
  • 431
  • 1
  • 6
  • 18

2 Answers2

5

If you don't really care for the DisplayName attribute, but the effective display name that will be used (for instance by data binding), the easiest is to use TypeDescriptor.GetProperties method:

var info = TypeDescriptor.GetProperties(typeof(Class1))
    .Cast<PropertyDescriptor>()
    .ToDictionary(p => p.Name, p => p.DisplayName);
Ivan Stoev
  • 195,425
  • 15
  • 312
  • 343
  • Thank you for the answer. I have encapsulated your code for working with Generic Class and it continue to works. You solve my problem! – Cyr Dec 15 '16 at 15:16
  • Would it be possible to get a dictionary with the values of the display names and a reference to the function itself? Even if this is only possible for static methods. – Reiner Sep 01 '17 at 08:57
  • @Reiner Not sure I follow, can you give an example? – Ivan Stoev Sep 01 '17 at 09:19
  • Lets assume that that the `[DisplayName("The ID number")] public static int Id { get; set; }` method would be added into a dictionary `Dictionary` as entry object: `{"The ID number", Class1.Id}` and could be used with `int id = dic["The ID number"]` – Reiner Sep 01 '17 at 09:45
  • @Reiner So you want a dictionary with display name being a key, and value being... hmm, not sure what. Most likely what you need is possible, but consider posting your own question with the specific requirement. – Ivan Stoev Sep 01 '17 at 13:09
0

You can use the code below -

 Class1 c = new Class1();
 PropertyInfo[] listPI = c.GetType().GetProperties();
 Dictionary<string, string> dictDisplayNames = new Dictionary<string, string>();
 string displayName = string.Empty;

 foreach (PropertyInfo pi in listPI)
 {
    DisplayNameAttribute dp = pi.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast<DisplayNameAttribute>().SingleOrDefault();
            if (dp != null)
            {
                displayName = dp.DisplayName;
                dictDisplayNames.Add(pi.Name, displayName);
            }
 }

I have also referred to same link that you have mentioned in the question.

the final dictionary is as -

enter image description here

Dhanashree
  • 235
  • 1
  • 3
  • 20
  • Thank you for the answer but unfortunately your code doesn't work on my project. – Cyr Dec 15 '16 at 15:44
  • what is the issue? – Dhanashree Dec 15 '16 at 15:45
  • It returns "Sequence contains no elements" in the displayName assignment into the foreach loop. – Cyr Dec 15 '16 at 15:48
  • Oh! sorry @Cyr there was a typo – Dhanashree Dec 15 '16 at 15:51
  • Oh! sorry @Cyr there was a typo, I have edited in the answer. It was inside the foreach loop - displayName = pi.GetCustomAttributes(typeof(DisplayNameAttribute), true).Cast().Single().DisplayName; – Dhanashree Dec 15 '16 at 15:52
  • Now it works. But if an attribute in the Model don't have the `[DisplayName("field name")]` DataAnnotation, it returns a System.InvalidOperationException (due to empty sequence). – Cyr Dec 15 '16 at 16:11
  • Then you have to add code to check if the attribute is null. I have edited the answer accordingly. – Dhanashree Dec 15 '16 at 16:17