how to use enum with DescriptionAttribute in asp.net mvc

前端 未结 4 1454
故里飘歌
故里飘歌 2021-02-07 06:02

I am new to asp.net MVC. I am trying to use dropdown control on my view page, which populates from enum. I also want to add custom descriptions to dropdown values. I searched so

相关标签:
4条回答
  • 2021-02-07 06:22

    The Html helper EnumDropDownListFor or EnumDropDownList does not take into consideration the Description attribute decorations on the enum members. However by reviewing the source code:

    Enum Dropdown List Helper: https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/SelectExtensions.cs

    Enum Helper Classes: https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/EnumHelper.cs

    The enum helper classes above are used to convert an Enum to a List<SelectListItem>. From the code below:

    // Return non-empty name specified in a [Display] attribute for the given field, if any; field's name otherwise
    private static string GetDisplayName(FieldInfo field)
    {
        DisplayAttribute display = field.GetCustomAttribute<DisplayAttribute>(inherit: false);
        if (display != null)
        {
            string name = display.GetName();
            if (!String.IsNullOrEmpty(name))
            {
                return name;
            }
        }
    
        return field.Name;
    }
    

    You can see that in the method GetDisplayName it checks for the existence of the DisplayAttribute on the enum member. If the display attribute exists then the name is set to the result of DisplayAttribute.GetName() method.

    Putting this together we can modify the enum to use the DisplayAttribute instead of the DescriptionAttribute and setting the Name property to the value you wish to display.

    public enum SearchBy
    {
        [Display(Name = "SID/PID")]
        SID = 1,
        [Display(Name = "Name")]
        Name,
        [Display(Name = "Birth Date")]
        DOB,
        [Display(Name = "Cause#")]
        Cause
    }
    

    This gives you the result you wish.

    enter image description here

    Hope this helps.

    0 讨论(0)
  • 2021-02-07 06:23

    Given :

    public enum MyEnum
    {
        [Description("This is the description if my member A")]
        A,
        [Description("This is the description if my member B")]
        B
    }
    

    I personally use this extension method to get a description from my enum:

     public static string GetDescription(this Enum value)
            {
                FieldInfo fi = value.GetType().GetField(value.ToString());
    
                DescriptionAttribute[] attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
    
                if (attributes != null && attributes.Length > 0)
                {
                    return attributes[0].Description;
                }
                else
                {
                    return value.ToString();
                }
            }
    

    To use it:

    MyEnum.A.GetDescription();
    

    Hope this help.

    0 讨论(0)
  • 2021-02-07 06:38

    I created a helper class that tries different types of attributes. I needed it because I was using bootstrap with https://github.com/civicsource/enums and https://silviomoreto.github.io/bootstrap-select/

    public static class EnumHelper<T>
        {
            static EnumHelper()
            {
                var enumType = typeof(T);
                if (!enumType.IsEnum) { throw new ArgumentException("Type '" + enumType.Name + "' is not an enum"); }
            }
    
            public static string GetEnumDescription(T value)
            {
                var fi = typeof(T).GetField(value.ToString());
                var attributes = (DescriptionAttribute[]) fi.GetCustomAttributes(typeof(DescriptionAttribute), false);
                return attributes.Length > 0 ? attributes[0].Description : value.ToString();
            }
    
            public static IEnumerable<SelectListItem> GetSelectList()
            {
                var groupDictionary = new Dictionary<string, SelectListGroup>();
    
                var enumType = typeof(T);
                var fields = from field in enumType.GetFields()
                             where field.IsLiteral
                             select field;
    
                foreach (var field in fields)
                {
                    var display = field.GetCustomAttribute<DisplayAttribute>(false);
                    var description = field.GetCustomAttribute<DescriptionAttribute>(false);
                    var group = field.GetCustomAttribute<CategoryAttribute>(false);
    
                    var text = display?.GetName() ?? display?.GetShortName() ?? display?.GetDescription() ?? display?.GetPrompt() ?? description?.Description ?? field.Name;
                    var value = field.Name;
                    var groupName = display?.GetGroupName() ?? group?.Category ?? string.Empty;
                    if (!groupDictionary.ContainsKey(groupName)) { groupDictionary.Add(groupName, new SelectListGroup { Name = groupName }); }
    
                    yield return new SelectListItem
                    {
                        Text = text,
                        Value = value,
                        Group = groupDictionary[groupName],
                    };
                }
            }
        }
    

    And you call it like:

    <div class="form-group">
       @Html.LabelFor(model => model.Address.State, htmlAttributes: new { @class = "control-label col-md-2" })
       <div class="col-sm-4">
          @Html.DropDownListFor(model => model.Address.State, EnumHelper<StateProvince>.GetSelectList(), new { @class = "selectpicker show-menu-arrow", data_live_search = "true" })
          @Html.ValidationMessageFor(model => model.Address.State, "", new { @class = "text-danger" })
       </div>
    </div>
    

    0 讨论(0)
  • 2021-02-07 06:39

    There is no need to create a helper class if you're using .Net Framework 4.0 or newer.

    You can just use the Display attribute in conjunction with EnumDropDownListFor

    public enum SearchBy
    {
        [Display(Name = "SID/PID")]
        SID = 1,
        [Display(Name = "Name")]
        Name,
        [Display(Name = "Birth Date")]
        DOB,
        [Display(Name = "Cause#")]
        Cause
    }
    

    In your View:

    @Html.EnumDropDownListFor(model => model.SearchBy, "Search By", new { @class = "form-control" })
    

    Microsoft documentation:

    https://docs.microsoft.com/en-us/dotnet/api/system.componentmodel.dataannotations.displayattribute?view=netframework-4.8

    0 讨论(0)
提交回复
热议问题