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

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

    Building on Simon's answer, a similar approach is to get the Enum values to display from a Resource file, instead of in a description attribute within the Enum itself. This is helpful if your site needs to be rendered in more than one language and if you were to have a specific resource file for Enums, you could go one step further and have just Enum values, in your Enum and reference them from the extension by a convention such as [EnumName]_[EnumValue] - ultimately less typing!

    The extension then looks like:

    public static IHtmlString EnumDropDownListFor(this HtmlHelper html, Expression> expression)
    {            
        var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
    
        var enumType = Nullable.GetUnderlyingType(metadata.ModelType) ?? metadata.ModelType;
    
        var enumValues = Enum.GetValues(enumType).Cast();
    
        var items = from enumValue in enumValues                        
                    select new SelectListItem
                    {
                        Text = GetResourceValueForEnumValue(enumValue),
                        Value = ((int)enumValue).ToString(),
                        Selected = enumValue.Equals(metadata.Model)
                    };
    
    
        return html.DropDownListFor(expression, items, string.Empty, null);
    }
    
    private static string GetResourceValueForEnumValue(TEnum enumValue)
    {
        var key = string.Format("{0}_{1}", enumValue.GetType().Name, enumValue);
    
        return Enums.ResourceManager.GetString(key) ?? enumValue.ToString();
    }
    
    
    

    Resources in the Enums.Resx file looking like ItemTypes_Movie : Film

    One other thing I like to do is, instead of calling the extension method directly, I'd rather call it with a @Html.EditorFor(x => x.MyProperty), or ideally just have the whole form, in one neat @Html.EditorForModel(). To do this I change the string template to look like this

    @using MVCProject.Extensions
    
    @{
        var type = Nullable.GetUnderlyingType(ViewData.ModelMetadata.ModelType) ?? ViewData.ModelMetadata.ModelType;
    
        @(typeof (Enum).IsAssignableFrom(type) ? Html.EnumDropDownListFor(x => x) : Html.TextBoxFor(x => x))
    }
    

    If this interests you, I've put a much more detailed answer here on my blog:

    http://paulthecyclist.com/2013/05/24/enum-dropdown/

    提交回复
    热议问题