当前位置:  开发笔记 > 编程语言 > 正文

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

如何解决《如何从ASP.NETMVC中的枚举创建下拉列表?》经验,为你挑选了16个好方法。

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

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

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

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

或者我最好的办法是简单地创建一个for循环并手动创建Html元素?



1> Martin Faart..:

对于MVC v5.1,使用Html.EnumDropDownListFor

@Html.EnumDropDownListFor(
    x => x.YourEnumField,
    "Select My Type", 
    new { @class = "form-control" })

对于MVC v5,请使用EnumHelper

@Html.DropDownList("MyType", 
   EnumHelper.GetSelectList(typeof(MyType)) , 
   "Select My Type", 
   new { @class = "form-control" })

对于MVC 5及更低版本

我将Rune的答案转换为扩展方法:

namespace MyApp.Common
{
    public static class MyExtensions{
        public static SelectList ToSelectList(this TEnum enumObj)
            where TEnum : struct, IComparable, IFormattable, IConvertible
        {
            var values = from TEnum e in Enum.GetValues(typeof(TEnum))
                select new { Id = e, Name = e.ToString() };
            return new SelectList(values, "Id", "Name", enumObj);
        }
    }
}

这允许你写:

ViewData["taskStatus"] = task.Status.ToSelectList();

通过 using MyApp.Common


我不能让它工作,你能帮忙吗?当我做Post.PostType.ToSelectList(); 它不承认扩展?
您可以使用以下内容对其进行一些限制:其中T:struct,IConvertible请参阅:http://stackoverflow.com/questions/79126/create-generic-method-constraining-t-to-an-enum
这很酷.如果有人正在努力实施这里我是如何做到的.在HtmlHelpers文件夹中添加了一个EnumHelpers类.使用上面的代码.根据@TodK建议添加命名空间:.然后我在剃刀页面中使用它:@ Html.DropDownListFor(model => model.Status,@ Model.Status.ToSelectList())HTH
请注意,在较新的`ASP.NET MVC`中有一种本地方式:http://stackoverflow.com/a/22295360/1361084
我也无法让这个工作.状态是您的Enum属性在任务类上?这不是枚举值之一吗?

2> SimonGoldsto..:

我知道我在这方面迟到了,但是你认为这个变种很有用,因为这个变体也允许你在下拉列表中使用描述性字符串而不是枚举常量.为此,请使用[System.ComponentModel.Description]属性装饰每个枚举条目.

例如:

public enum TestEnum
{
  [Description("Full test")]
  FullTest,

  [Description("Incomplete or partial test")]
  PartialTest,

  [Description("No test performed")]
  None
}

这是我的代码:

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

然后,您可以在视图中执行此操作:

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

希望这对你有所帮助!

**编辑2014年1月23日:微软刚刚发布MVC 5.1,现在有一个EnumDropDownListFor功能.遗憾的是,它似乎不尊重[Description]属性,因此上面的代码仍然有效.请参阅Microsoft的MVC 5.1发行说明中的Enum部分.

更新:它确实支持Display属性[Display(Name = "Sample")],因此可以使用它.

[更新 - 只是注意到这一点,代码看起来像这里的代码的扩展版本:https://blogs.msdn.microsoft.com/stuartleeks/2010/05/21/asp-net-mvc-creating-a- dropdownlist-helper-for-enums /,有几个附加功能.如果是这样,归属似乎是公平的;-)]


Visual Studio有一个奇怪的错误,如果你不引用`System.Web.Mvc.Html`,那么就说找不到'DropDownListFor`,但它也无法解决它.你必须手动执行`using System.Web.Mvc.Html;`.你好吗?
+1我在这里找到了最有用的所有答案.我能够将其转换为高度可重用的代码片段.谢谢!
新的MVC 5.1 EnumDropDownListFor不使用[Description("")]但它确实使用[Display(Name ="")]!请享用 :)

3> Ofiris..:

ASP.NET MVC 5.1中,他们添加了EnumDropDownListFor()帮助程序,因此不需要自定义扩展:

型号:

public enum MyEnum
{
    [Display(Name = "First Value - desc..")]
    FirstValue,
    [Display(Name = "Second Value - desc...")]
    SecondValue
}

查看:

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

使用Tag Helper(ASP.NET MVC 6):


    
    
    

请注意,用于调用ToSelectListon的项目是所选项目.



15> 小智..:

这是Razor的版本:

@{
    var itemTypesList = new List();
    itemTypesList.AddRange(Enum.GetValues(typeof(ItemTypes)).Cast().Select(
                (item, index) => new SelectListItem
                {
                    Text = item.ToString(),
                    Value = (index).ToString(),
                    Selected = Model.ItemTypeId == index
                }).ToList());
 }


@Html.DropDownList("ItemTypeId", itemTypesList)



16> Lafi..:

现在,通过以下方式在MVC 5.1中可以立即使用此功能: @Html.EnumDropDownListFor()

检查以下链接:

https://docs.microsoft.com/zh-cn/aspnet/mvc/overview/releases/mvc51-release-notes#Enum

根据上面的投票,微软花了5年的时间来实现如此受欢迎的功能,真是太可惜了!

推荐阅读