How do you create a dropdownlist from an enum in ASP.NET MVC?

后端 未结 30 1889
不知归路
不知归路 2020-11-21 16:36

I\'m trying to use the Html.DropDownList extension method but can\'t figure out how to use it with an enumeration.

Let\'s say I have an enumeration like

30条回答
  •  梦如初夏
    2020-11-21 16:58

    I know I'm late to the party on this, but thought you might find this variant useful, as this one also allows you to use descriptive strings rather than enumeration constants in the drop down. To do this, decorate each enumeration entry with a [System.ComponentModel.Description] attribute.

    For example:

    public enum TestEnum
    {
      [Description("Full test")]
      FullTest,
    
      [Description("Incomplete or partial test")]
      PartialTest,
    
      [Description("No test performed")]
      None
    }
    

    Here is my code:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.Mvc;
    using System.Web.Mvc.Html;
    using System.Reflection;
    using System.ComponentModel;
    using System.Linq.Expressions;
    
     ...
    
     private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
        {
            Type realModelType = modelMetadata.ModelType;
    
            Type underlyingType = Nullable.GetUnderlyingType(realModelType);
            if (underlyingType != null)
            {
                realModelType = underlyingType;
            }
            return realModelType;
        }
    
        private static readonly SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = "", Value = "" } };
    
        public static string GetEnumDescription(TEnum 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();
        }
    
        public static MvcHtmlString EnumDropDownListFor(this HtmlHelper htmlHelper, Expression> expression)
        {
            return EnumDropDownListFor(htmlHelper, expression, null);
        }
    
        public static MvcHtmlString EnumDropDownListFor(this HtmlHelper htmlHelper, Expression> expression, object htmlAttributes)
        {
            ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
            Type enumType = GetNonNullableModelType(metadata);
            IEnumerable values = Enum.GetValues(enumType).Cast();
    
            IEnumerable items = from value in values
                select new SelectListItem
                {
                    Text = GetEnumDescription(value),
                    Value = value.ToString(),
                    Selected = value.Equals(metadata.Model)
                };
    
            // If the enum is nullable, add an 'empty' item to the collection
            if (metadata.IsNullableValueType)
                items = SingleEmptyItem.Concat(items);
    
            return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
        }
    

    You can then do this in your view:

    @Html.EnumDropDownListFor(model => model.MyEnumProperty)
    

    Hope this helps you!

    **EDIT 2014-JAN-23: Microsoft have just released MVC 5.1, which now has an EnumDropDownListFor feature. Sadly it does not appear to respect the [Description] attribute so the code above still stands.See Enum section in Microsoft's release notes for MVC 5.1.

    Update: It does support the Display attribute [Display(Name = "Sample")] though, so one can use that.

    [Update - just noticed this, and the code looks like an extended version of the code here: https://blogs.msdn.microsoft.com/stuartleeks/2010/05/21/asp-net-mvc-creating-a-dropdownlist-helper-for-enums/, with a couple of additions. If so, attribution would seem fair ;-)]

提交回复
热议问题