如何从ASP.NET MVC中的枚举创建下拉列表?

给你一囗甜甜゛ 提交于 2019-12-27 18:04:35

【推荐】2019 Java 开发者跳槽指南.pdf(吐血整理) >>>

我正在尝试使用Html.DropDownList扩展方法,但无法弄清楚如何在枚举中使用它。

假设我有一个这样的枚举:

public enum ItemTypes
{
    Movie = 1,
    Game = 2,
    Book = 3
}

如何使用Html.DropDownList扩展方法使用这些值创建下拉列表?

还是我最好的选择就是简单地创建一个for循环并手动创建HTML元素?


#1楼

最后,我创建了扩展方法来执行本质上是这里接受答案的方法。 要点的后半部分专门针对Enum。

https://gist.github.com/3813767


#2楼

我对此很迟,但是如果您乐于添加Unconstrained Melody NuGet软件包(Jon Skeet的一个不错的小型库),那么我只用一行代码就找到了一种非常酷的方法。

此解决方案更好,因为:

  1. 它确保(带有通用类型约束)该值确实是一个枚举值(由于不受约束的旋律)
  2. 避免不必要的拳击(由于不受限制的旋律)
  3. 它缓存所有描述,以避免在每个呼叫中​​使用反射(由于无约束旋律)
  4. 它比其他解决方案少的代码!

因此,以下是使此工作正常进行的步骤:

  1. 在程序包管理器控制台中,“安装程序包不受约束的旋律”
  2. 在模型上添加一个属性,如下所示:

    //Replace "YourEnum" with the type of your enum public IEnumerable<SelectListItem> AllItems { get { return Enums.GetValues<YourEnum>().Select(enumValue => new SelectListItem { Value = enumValue.ToString(), Text = enumValue.GetDescription() }); } }

现在,您已经在模型上暴露了SelectListItem的列表,您可以使用@ Html.DropDownList或@ Html.DropDownListFor将此属性用作源。


#3楼

这是一个更好的封装解决方案:

https://www.spicelogic.com/Blog/enum-dropdownlistfor-asp-net-mvc-5

说这是您的模型:

样品用法:

生成的UI:

并生成HTML

Helper Extension源代码快照:

您可以从我提供的链接下载示例项目。

编辑:这是代码:

public static class EnumEditorHtmlHelper
{
    /// <summary>
    /// Creates the DropDown List (HTML Select Element) from LINQ 
    /// Expression where the expression returns an Enum type.
    /// </summary>
    /// <typeparam name="TModel">The type of the model.</typeparam>
    /// <typeparam name="TProperty">The type of the property.</typeparam>
    /// <param name="htmlHelper">The HTML helper.</param>
    /// <param name="expression">The expression.</param>
    /// <returns></returns>
    public static MvcHtmlString DropDownListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
        Expression<Func<TModel, TProperty>> expression) 
        where TModel : class
    {
        TProperty value = htmlHelper.ViewData.Model == null 
            ? default(TProperty) 
            : expression.Compile()(htmlHelper.ViewData.Model);
        string selected = value == null ? String.Empty : value.ToString();
        return htmlHelper.DropDownListFor(expression, createSelectList(expression.ReturnType, selected));
    }

    /// <summary>
    /// Creates the select list.
    /// </summary>
    /// <param name="enumType">Type of the enum.</param>
    /// <param name="selectedItem">The selected item.</param>
    /// <returns></returns>
    private static IEnumerable<SelectListItem> createSelectList(Type enumType, string selectedItem)
    {
        return (from object item in Enum.GetValues(enumType)
                let fi = enumType.GetField(item.ToString())
                let attribute = fi.GetCustomAttributes(typeof (DescriptionAttribute), true).FirstOrDefault()
                let title = attribute == null ? item.ToString() : ((DescriptionAttribute) attribute).Description
                select new SelectListItem
                  {
                      Value = item.ToString(), 
                      Text = title, 
                      Selected = selectedItem == item.ToString()
                  }).ToList();
    }
}

#4楼

基于Simon的答案,一种类似的方法是从资源文件中获取要显示的Enum值,而不是在Enum本身的description属性中显示。 如果您的网站需要使用多种语言呈现,并且要为Enums使用特定的资源文件,则这将很有帮助,您可以再进一步一步,在Enum中仅包含Enum值,并通过扩展名引用它们约定,例如[EnumName] _ [EnumValue]-最终减少了打字!

扩展名如下所示:

public static IHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> html, Expression<Func<TModel, TEnum>> expression)
{            
    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);

    var enumType = Nullable.GetUnderlyingType(metadata.ModelType) ?? metadata.ModelType;

    var enumValues = Enum.GetValues(enumType).Cast<object>();

    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>(TEnum enumValue)
{
    var key = string.Format("{0}_{1}", enumValue.GetType().Name, enumValue);

    return Enums.ResourceManager.GetString(key) ?? enumValue.ToString();
}

Enums.Resx文件中的资源类似于ItemTypes_Movie:Film

我想做的另一件事是,与其直接调用扩展方法,不如使用@ Html.EditorFor(x => x.MyProperty)进行调用,或者理想情况下使用整齐的@形式完整地@ Html.EditorForModel()。 为此,我将字符串模板更改为如下形式

@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))
}

如果您对此感兴趣,我会在这里在博客上提供更详细的答案:

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


#5楼

@Html.DropdownListFor(model=model->Gender,new List<SelectListItem>
{
 new ListItem{Text="Male",Value="Male"},
 new ListItem{Text="Female",Value="Female"},
 new ListItem{Text="--- Select -----",Value="-----Select ----"}
}
)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!