Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 982
developer033 Avatar asked May 26 '15 19:05

developer033


People also ask

What is enum and example?

An enum type is a special data type that enables for a variable to be a set of predefined constants. The variable must be equal to one of the values that have been predefined for it. Common examples include compass directions (values of NORTH, SOUTH, EAST, and WEST) and the days of the week.

What enum means?

Enumeration or Enum in C is a special kind of data type defined by the user. It consists of constant integrals or integers that are given names by a user. The use of enum in C to name the integer values makes the entire program easy to learn, understand, and maintain by the same or even different programmer.

What is enum system?

An Enum is a named constant whose underlying type is any integral type except Char. If no underlying type is explicitly declared, Int32 is used. Enum derives from ValueType, but is not a value type.

What is enum data?

An enumeration is a data type that consists of a set of named values that represent integral constants, known as enumeration constants. An enumeration is also referred to as an enumerated type because you must list (enumerate) each of the values in creating a name for each of them.


3 Answers

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)]
like image 73
akousmata Avatar answered Sep 20 '22 15:09

akousmata


Here's a simplified (and working) version of akousmata's localized enum extension:

public static string DisplayName(this Enum enumValue)
{
    var enumType = enumValue.GetType();
    var memberInfo = enumType.GetMember(enumValue.ToString()).First();

    if (memberInfo == null || !memberInfo.CustomAttributes.Any()) return enumValue.ToString();

    var displayAttribute = memberInfo.GetCustomAttribute<DisplayAttribute>();

    if (displayAttribute == null) return enumValue.ToString();

    if (displayAttribute.ResourceType != null && displayAttribute.Name != null)
    {
        var manager = new ResourceManager(displayAttribute.ResourceType);
        return manager.GetString(displayAttribute.Name);
    }

    return displayAttribute.Name ?? enumValue.ToString();
}

Note: I move enumType from a parameter to a local variable.

Example usage:

public enum IndexGroupBy 
{
    [Display(Name = "By Alpha")]
    ByAlpha,
    [Display(Name = "By Type")]
    ByType
}

And

@IndexGroupBy.ByAlpha.DisplayName()

Here is a editor template that can be used with the extension method above:

@model Enum

@{    
    var listItems = Enum.GetValues(Model.GetType()).OfType<Enum>().Select(e =>
        new SelectListItem
        {
            Text = e.DisplayName(),
            Value = e.ToString(),
            Selected = e.Equals(Model)
        });
    var prefix = ViewData.TemplateInfo.HtmlFieldPrefix;
    var index = 0;
    ViewData.TemplateInfo.HtmlFieldPrefix = string.Empty;

    foreach (var li in listItems)
    {
        var fieldName = string.Format(CultureInfo.InvariantCulture, "{0}_{1}", prefix, index++);
        <div class="editor-radio">
            @Html.RadioButton(prefix, li.Value, li.Selected, new {@id = fieldName})
            @Html.Label(fieldName, li.Text)
        </div>
    }
    ViewData.TemplateInfo.HtmlFieldPrefix = prefix;
}

And here is an example usage:

@Html.EditorFor(m => m.YourEnumMember, "Enum_RadioButtonList")
like image 44
Mark Good Avatar answered Sep 20 '22 15:09

Mark Good


Since you are worrying about visuals I would use a configurable approach:

public NotebookTypes NotebookType;

public enum NotebookTypes{
   NotebookHP,
   NotebookDell
}

public string NotebookTypeName{
   get{
      switch(NotebookType){
         case NotebookTypes.NotebookHP:
            return "Notebook HP"; //You may read the language dependent value from xml...
         case NotebookTypes.NotebookDell:
            return "Notebook Dell"; //You may read the language dependent value from xml...
         default:
            throw new NotImplementedException("'" + typeof(NotebookTypes).Name + "." + NotebookType.ToString() + "' is not implemented correctly.");
      }
   }
}
like image 22
Noel Widmer Avatar answered Sep 19 '22 15:09

Noel Widmer