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

后端 未结 30 2309
不知归路
不知归路 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:56

    The best solution I found for this was combining this blog with Simon Goldstone's answer.

    This allows use of the enum in the model. Essentially the idea is to use an integer property as well as the enum, and emulate the integer property.

    Then use the [System.ComponentModel.Description] attribute for annotating the model with your display text, and use an "EnumDropDownListFor" extension in your view.

    This makes both the view and model very readable and maintainable.

    Model:

    public enum YesPartialNoEnum
    {
        [Description("Yes")]
        Yes,
        [Description("Still undecided")]
        Partial,
        [Description("No")]
        No
    }
    
    //........
    
    [Display(Name = "The label for my dropdown list")]
    public virtual Nullable CuriousQuestion{ get; set; }
    public virtual Nullable CuriousQuestionId
    {
        get { return (Nullable)CuriousQuestion; }
        set { CuriousQuestion = (Nullable)value; }
    }
    

    View:

    @using MyProject.Extensions
    {
    //...
        @Html.EnumDropDownListFor(model => model.CuriousQuestion)
    //...
    }
    

    Extension (directly from Simon Goldstone's answer, included here for completeness):

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web;
    using System.Web.Mvc;
    using System.ComponentModel;
    using System.Reflection;
    using System.Linq.Expressions;
    using System.Web.Mvc.Html;
    
    namespace MyProject.Extensions
    {
        //Extension methods must be defined in a static class
        public static class MvcExtensions
        {
            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);
            }
        }
    }
    

提交回复
热议问题