Search code examples
c#enumsdata-annotationsasp.net-mvc-5.2displayattribute

About Enum and DataAnnotation


I have this Enum (Notebook.cs):

public enum Notebook : byte
{
   [Display(Name = "Notebook HP")]
   NotebookHP,

   [Display(Name = "Notebook Dell")]
   NotebookDell
}

Also this property in my class (TIDepartment.cs):

public Notebook Notebook { get; set; }

It's working perfectly, I just have one "problem":

I created an EnumDDLFor and it's showing the name I setted in DisplayAttribute, with spaces, but the object doesn't receive that name in DisplayAttribute, receives the Enum name (what is correct), so my question is:

Is there a way to receive the name with spaces which one I configured in DisplayAttribute?


Solution

  • MVC doesn't make use of the Display attribute on enums (or any framework I'm aware of). You need to create a custom Enum extension class:

    public static class EnumExtensions
    {
        public static string GetDisplayAttributeFrom(this Enum enumValue, Type enumType)
        {
            string displayName = "";
            MemberInfo info = enumType.GetMember(enumValue.ToString()).First();
    
            if (info != null && info.CustomAttributes.Any())
            {
                DisplayAttribute nameAttr = info.GetCustomAttribute<DisplayAttribute>();
                displayName = nameAttr != null ? nameAttr.Name : enumValue.ToString();
            }
            else
            {
                displayName = enumValue.ToString();
            }
            return displayName;
        }
    }
    

    Then you can use it like this:

    Notebook n = Notebook.NotebookHP;
    String displayName = n.GetDisplayAttributeFrom(typeof(Notebook));
    

    EDIT: Support for localization

    This may not be the most efficient way, but SHOULD work.

    public static class EnumExtensions
    {
        public static string GetDisplayAttributeFrom(this Enum enumValue, Type enumType)
        {
            string displayName = "";
            MemberInfo info = enumType.GetMember(enumValue.ToString()).First();
    
            if (info != null && info.CustomAttributes.Any())
            {
                DisplayAttribute nameAttr = info.GetCustomAttribute<DisplayAttribute>();
    
                if(nameAttr != null) 
                {
                    // Check for localization
                    if(nameAttr.ResourceType != null && nameAttr.Name != null)
                    {
                        // I recommend not newing this up every time for performance
                        // but rather use a global instance or pass one in
                        var manager = new ResourceManager(nameAttr.ResourceType);
                        displayName = manager.GetString(nameAttr.Name)
                    }
                    else if (nameAttr.Name != null)
                    {
                        displayName = nameAttr != null ? nameAttr.Name : enumValue.ToString();
                    }
                }
            }
            else
            {
                displayName = enumValue.ToString();
            }
            return displayName;
        }
    }
    

    On the enum, the key and resource type must be specified:

    [Display(Name = "MyResourceKey", ResourceType = typeof(MyResourceFile)]