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

我试图使用Html.DropDownList扩展方法,但无法弄清楚如何使用枚举。

比方说,我有这样的枚举:

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

我该如何使用Html.DropDownList扩展方法来创build具有这些值的下拉菜单?

或者,我最好只是简单地创build一个for循环并手动创buildHtml元素?

对于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和更低

我把符文的答案翻译成扩展方法:

 namespace MyApp.Common { public static class MyExtensions{ public static SelectList ToSelectList<TEnum>(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

我知道我对这个派对迟到了,但是认为你可能会发现这个变体是有用的,因为这个也允许你在下拉列表中使用描述性string而不是枚举常量。 为此,请使用[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>(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<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression) { return EnumDropDownListFor(htmlHelper, expression, null); } public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes) { ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); Type enumType = GetNonNullableModelType(metadata); IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>(); IEnumerable<SelectListItem> 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,现在有一个EnumDropDownListForfunction。 可悲的是,它似乎没有尊重[Description]属性,所以上面的代码仍然存在。 (有关 Microsoft发行说明, 请参阅http://www.asp.net/mvc/overview/releases/mvc51-release-notes#Enum 。)

更新:虽然支持Display属性[Display(Name = "Sample")] ,所以可以使用它。

[更新 – 只是注意到了这一点,代码看起来像一个扩展版本的代码在这里: http : //blogs.msdn.com/b/stuartleeks/archive/2010/05/21/asp-net-mvc-creating- a-dropdownlist-helper-for-enums.aspx ,还有一些补充。 如果是这样,归因会看起来公平;-)]

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) 

使用标签助手(ASP.NET MVC 6)

 <select asp-for="@Model.SelectedValue" asp-items="Html.GetEnumSelectList<MyEnum>()"> 

我遇到了同样的问题,发现了这个问题,并认为Ash提供的解决scheme并不是我所期待的。 与内置的Html.DropDownList()函数相比,自己创buildHTML意味着更less的灵活性。

原来C#3等,这很容易。 我有一个名为TaskStatusenum

 var statuses = from TaskStatus s in Enum.GetValues(typeof(TaskStatus)) select new { ID = s, Name = s.ToString() }; ViewData["taskStatus"] = new SelectList(statuses, "ID", "Name", task.Status); 

这创build了一个很好的SelectList ,可以像你习惯的那样在视图中使用:

 <td><b>Status:</b></td><td><%=Html.DropDownList("taskStatus")%></td></tr> 

匿名types和LINQ使这个更加优雅恕我直言。 Ash没有任何意图。 🙂

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

http://www.spicelogic.com/Journal/ASP-NET-MVC-DropDownListFor-Html-Helper-Enum-5

说这里是你的模型:

在这里输入图像描述

样本用法:

在这里输入图像描述

生成的用户界面: 在这里输入图像描述

并生成HTML

在这里输入图像描述

助手扩展源代码快照:

在这里输入图像描述

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

编辑:这是代码:

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

Html.DropDownListFor只需要一个IEnumerable,所以Prize的解决scheme的替代方法如下。 这将允许你简单地写:

 @Html.DropDownListFor(m => m.SelectedItemType, Model.SelectedItemType.ToSelectList()) 

[其中SelectedItemType是您的模型typesItemTypes上的字段,并且您的模型是非空]

此外,您不需要泛化扩展方法,因为您可以使用enumValue.GetType()而不是typeof(T)。

编辑:西蒙的综合解决scheme,以及包括ToDescription扩展方法。

 public static class EnumExtensions { public static IEnumerable<SelectListItem> ToSelectList(this Enum enumValue) { return from Enum e in Enum.GetValues(enumValue.GetType()) select new SelectListItem { Selected = e.Equals(enumValue), Text = e.ToDescription(), Value = e.ToString() }; } public static string ToDescription(this Enum value) { var attributes = (DescriptionAttribute[])value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false); return attributes.Length > 0 ? attributes[0].Description : value.ToString(); } } 

所以没有扩展function,如果你正在寻找简单和容易..这是我做的

 <%= Html.DropDownListFor(x => x.CurrentAddress.State, new SelectList(Enum.GetValues(typeof(XXXXX.Sites.YYYY.Models.State))))%> 

其中XXXXX.Sites.YYYY.Models.State是一个枚举

可能更好的帮助function,但时间短,这将完成工作。

如果您希望将select列表项的值属性映射到枚举types的整数值而不是string值,请使用以下代码扩展奖和符文的答案:

 public static SelectList ToSelectList<T, TU>(T enumObj) where T : struct where TU : struct { if(!typeof(T).IsEnum) throw new ArgumentException("Enum is required.", "enumObj"); var values = from T e in Enum.GetValues(typeof(T)) select new { Value = (TU)Convert.ChangeType(e, typeof(TU)), Text = e.ToString() }; return new SelectList(values, "Value", "Text", enumObj); } 

我们可以将每个枚举值视为一个TEnum对象,而不是将其视为一个对象,然后将其转换为整数以获得取消装箱值。

注意:我还添加了一个genericstypes约束来限制只有结构体(Enum的基types)可以使用这个扩展的types,以及确保传入的结构体确实是一个Enum的运行时typesvalidation。

2012年12月23日更新:为基础types添加了genericstypes参数,并修正了影响.NET 4+的非编译问题。

用Prize的扩展方法来解决数字而不是文本的问题。

 public static SelectList ToSelectList<TEnum>(this TEnum enumObj) { var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString()) , Name = e.ToString() }; return new SelectList(values, "Id", "Name", enumObj); } 

我find的最好的解决办法是把这个博客与Simon Goldstone的答案结合起来。

这允许在模型中使用枚举。 基本上这个想法是使用整数属性以及枚举,并模拟整数属性。

然后使用[System.ComponentModel.Description]属性为显示文本注释模型,并在视图中使用“EnumDropDownListFor”扩展名。

这使得视图和模型都非常可读和可维护。

模型:

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

视图:

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

扩展(直接来自Simon Goldstone的答案 ,这里包括完整性):

 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>(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<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression) { return EnumDropDownListFor(htmlHelper, expression, null); } public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes) { ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData); Type enumType = GetNonNullableModelType(metadata); IEnumerable<TEnum> values = Enum.GetValues(enumType).Cast<TEnum>(); IEnumerable<SelectListItem> 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); } } } 

你想看看使用像Enum.GetValues

一个超级简单的方法来完成这件事 – 没有所有的扩展东西,似乎矫枉过正是这样的:

你的枚举:

  public enum SelectedLevel { Level1, Level2, Level3, Level4 } 

控制器内部将Enum绑定到列表:

  List<SelectedLevel> myLevels = Enum.GetValues(typeof(SelectedLevel)).Cast<SelectedLevel>().ToList(); 

之后,把它扔进ViewBag:

  ViewBag.RequiredLevel = new SelectList(myLevels); 

最后只需将其绑定到视图:

  @Html.DropDownList("selectedLevel", (SelectList)ViewBag.RequiredLevel, new { @class = "form-control" }) 

这是我发现的最简单的方法,不需要任何扩展或任何疯狂的东西。

更新 :见下面的安德鲁斯评论。

这是符文和奖的答案更改为使用Enum int值作为ID。

样本枚举:

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

扩展方法:

  public static SelectList ToSelectList<TEnum>(this TEnum enumObj) { var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { Id = (int)Enum.Parse(typeof(TEnum), e.ToString()), Name = e.ToString() }; return new SelectList(values, "Id", "Name", (int)Enum.Parse(typeof(TEnum), enumObj.ToString())); } 

使用示例:

  <%= Html.DropDownList("MyEnumList", ItemTypes.Game.ToSelectList()) %> 

请记住导入包含扩展方法的名称空间

 <%@ Import Namespace="MyNamespace.LocationOfExtensionMethod" %> 

生成的HTML示例:

 <select id="MyEnumList" name="MyEnumList"> <option value="1">Movie</option> <option selected="selected" value="2">Game</option> <option value="3">Book </option> </select> 

请注意,您用于调用ToSelectList的项目是所选项目。

 @Html.DropDownListFor(model => model.Type, Enum.GetNames(typeof(Rewards.Models.PropertyType)).Select(e => new SelectListItem { Text = e })) 

这是Razor的版本:

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

如果你很高兴地添加Unconstrained Melody NuGet包(Jon Skeet的一个很好的小图书馆),我在这一个上很晚了,但是我发现了一个很酷的方法来完成这一行代码。

这个解决scheme更好,因为:

  1. 它确保(通用types约束)该值实际上是一个枚举值(由于无约束的旋律)
  2. 它避免了不必要的拳击(由于无约束的旋律)
  3. 它caching所有的描述,以避免在每次通话中使用reflection(由于无约束的旋律)
  4. 这是比其他解决scheme更less的代码!

所以,下面是这个工作的步骤:

  1. 在软件包pipe理器控制台中,“Install-Package UnconstrainedMelody”
  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使用此属性作为源。

基于Simon的回答,类似的方法是从Enum中获取Enum值,而不是Enum本身的描述属性。 如果您的站点需要使用多种语言进行渲染,并且如果要为Enums指定一个特定的资源文件,那么这很有帮助,您可以更进一步,并在Enum中添加Enum值,并通过扩展名引用它们例如[EnumName] _ [EnumValue]这样的约定 – 最终less打字!

然后,扩展名如下所示:

 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()。 要做到这一点,我改变string模板看起来像这样

 @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/

现在,通过@Html.EnumDropDownListFor()在MVC 5.1中支持此function。

检查以下链接:

http://www.asp.net/mvc/overview/releases/mvc51-release-notes#Enum

根据上面的投票,微软用了5年的时间来实现如此需求的function真是令人遗憾!

此扩展方法的另一个修复 – 当前版本不select枚举的当前值。 我修正了最后一行:

 public static SelectList ToSelectList<TEnum>(this TEnum enumObj) where TEnum : struct { if (!typeof(TEnum).IsEnum) throw new ArgumentException("An Enumeration type is required.", "enumObj"); var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = (int)Enum.Parse(typeof(TEnum), e.ToString()), Name = e.ToString() }; return new SelectList(values, "ID", "Name", ((int)Enum.Parse(typeof(TEnum), enumObj.ToString())).ToString()); } 

如果您想添加本地化支持,只需将s.toString()方法更改为如下所示:

 ResourceManager rManager = new ResourceManager(typeof(Resources)); var dayTypes = from OperatorCalendarDay.OperatorDayType s in Enum.GetValues(typeof(OperatorCalendarDay.OperatorDayType)) select new { ID = s, Name = rManager.GetString(s.ToString()) }; 

在这里,typeof(资源)是你想要加载的资源,然后你得到本地化的string,也是有用的,如果你的枚举数具有多个字的值。

这是我的辅助方法的版本。 我使用这个:

 var values = from int e in Enum.GetValues(typeof(TEnum)) select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) }; 

而不是:

 var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { ID = (int)Enum.Parse(typeof(TEnum),e.ToString()) , Name = e.ToString() }; 

这里是:

 public static SelectList ToSelectList<TEnum>(this TEnum self) where TEnum : struct { if (!typeof(TEnum).IsEnum) { throw new ArgumentException("self must be enum", "self"); } Type t = typeof(TEnum); var values = from int e in Enum.GetValues(typeof(TEnum)) select new { ID = e, Name = Enum.GetName(typeof(TEnum), e) }; return new SelectList(values, "ID", "Name", self); } 

You can also use my custom HtmlHelpers in Griffin.MvcContrib. 以下代码:

 @Html2.CheckBoxesFor(model => model.InputType) <br /> @Html2.RadioButtonsFor(model => model.InputType) <br /> @Html2.DropdownFor(model => model.InputType) <br /> 

Generates:

在这里输入图像描述

https://github.com/jgauffin/griffin.mvccontrib

Well I'm really late to the party, but for what it is worth, I have blogged about this very subject whereby I create a EnumHelper class that enables very easy transformation.

http://jnye.co/Posts/4/creating-a-dropdown-list-from-an-enum-in-mvc-and-c%23

In your controller:

 //If you don't have an enum value use the type ViewBag.DropDownList = EnumHelper.SelectListFor<MyEnum>(); //If you do have an enum value use the value (the value will be marked as selected) ViewBag.DropDownList = EnumHelper.SelectListFor(MyEnum.MyEnumValue); 

In your View:

 @Html.DropDownList("DropDownList") @* OR *@ @Html.DropDownListFor(m => m.Property, ViewBag.DropDownList as SelectList, null) 

The helper class:

 public static class EnumHelper { // Get the value of the description attribute if the // enum has one, otherwise use the value. public static string GetDescription<TEnum>(this TEnum value) { var fi = value.GetType().GetField(value.ToString()); if (fi != null) { var attributes = (DescriptionAttribute[])fi.GetCustomAttributes(typeof(DescriptionAttribute), false); if (attributes.Length > 0) { return attributes[0].Description; } } return value.ToString(); } /// <summary> /// Build a select list for an enum /// </summary> public static SelectList SelectListFor<T>() where T : struct { Type t = typeof(T); return !t.IsEnum ? null : new SelectList(BuildSelectListItems(t), "Value", "Text"); } /// <summary> /// Build a select list for an enum with a particular value selected /// </summary> public static SelectList SelectListFor<T>(T selected) where T : struct { Type t = typeof(T); return !t.IsEnum ? null : new SelectList(BuildSelectListItems(t), "Text", "Value", selected.ToString()); } private static IEnumerable<SelectListItem> BuildSelectListItems(Type t) { return Enum.GetValues(t) .Cast<Enum>() .Select(e => new SelectListItem { Value = e.ToString(), Text = e.GetDescription() }); } } 

@Simon Goldstone: Thanks for your solution, it can be perfectly applied in my case. The only problem is I had to translate it to VB. But now it is done and to save other people's time (in case they need it) I put it here:

 Imports System.Runtime.CompilerServices Imports System.ComponentModel Imports System.Linq.Expressions Public Module HtmlHelpers Private Function GetNonNullableModelType(modelMetadata As ModelMetadata) As Type Dim realModelType = modelMetadata.ModelType Dim underlyingType = Nullable.GetUnderlyingType(realModelType) If Not underlyingType Is Nothing Then realModelType = underlyingType End If Return realModelType End Function Private ReadOnly SingleEmptyItem() As SelectListItem = {New SelectListItem() With {.Text = "", .Value = ""}} Private Function GetEnumDescription(Of TEnum)(value As TEnum) As String Dim fi = value.GetType().GetField(value.ToString()) Dim attributes = DirectCast(fi.GetCustomAttributes(GetType(DescriptionAttribute), False), DescriptionAttribute()) If Not attributes Is Nothing AndAlso attributes.Length > 0 Then Return attributes(0).Description Else Return value.ToString() End If End Function <Extension()> Public Function EnumDropDownListFor(Of TModel, TEnum)(ByVal htmlHelper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TEnum))) As MvcHtmlString Return EnumDropDownListFor(htmlHelper, expression, Nothing) End Function <Extension()> Public Function EnumDropDownListFor(Of TModel, TEnum)(ByVal htmlHelper As HtmlHelper(Of TModel), expression As Expression(Of Func(Of TModel, TEnum)), htmlAttributes As Object) As MvcHtmlString Dim metaData As ModelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData) Dim enumType As Type = GetNonNullableModelType(metaData) Dim values As IEnumerable(Of TEnum) = [Enum].GetValues(enumType).Cast(Of TEnum)() Dim items As IEnumerable(Of SelectListItem) = From value In values Select New SelectListItem With { .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 Then items = SingleEmptyItem.Concat(items) End If Return htmlHelper.DropDownListFor(expression, items, htmlAttributes) End Function End Module 

End You use it like this:

 @Html.EnumDropDownListFor(Function(model) (model.EnumField)) 

I ended up creating extention methods to do what is essentially the accept answer here. The last half of the Gist deals with Enum specifically.

https://gist.github.com/3813767

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

I found an answer here http://blogs.msdn.com/b/stuartleeks/archive/2010/05/21/asp-net-mvc-creating-a-dropdownlist-helper-for-enums.aspx ; however, some of my enums have [Description(...)] attribute, so I've modified the code to provide support for that:

  enum Abc { [Description("Cba")] Abc, Def } public static MvcHtmlString EnumDropDownList<TEnum>(this HtmlHelper htmlHelper, string name, TEnum selectedValue) { IEnumerable<TEnum> values = Enum.GetValues(typeof(TEnum)) .Cast<TEnum>(); List<SelectListItem> items = new List<SelectListItem>(); foreach (var value in values) { string text = value.ToString(); var member = typeof(TEnum).GetMember(value.ToString()); if (member.Count() > 0) { var customAttributes = member[0].GetCustomAttributes(typeof(DescriptionAttribute), false); if (customAttributes.Count() > 0) { text = ((DescriptionAttribute)customAttributes[0]).Description; } } items.Add(new SelectListItem { Text = text, Value = value.ToString(), Selected = (value.Equals(selectedValue)) }); } return htmlHelper.DropDownList( name, items ); } 

希望有所帮助。

 @Html.DropDownListFor(model => model.MaritalStatus, new List<SelectListItem> { new SelectListItem { Text = "----Select----", Value = "-1" }, new SelectListItem { Text = "Marrid", Value = "M" }, new SelectListItem { Text = "Single", Value = "S" } }) 

1- Create your ENUM

 public enum LicenseType { xxx = 1, yyy = 2 } 

2- Create your Service Class

 public class LicenseTypeEnumService { public static Dictionary<int, string> GetAll() { var licenseTypes = new Dictionary<int, string>(); licenseTypes.Add((int)LicenseType.xxx, "xxx"); licenseTypes.Add((int)LicenseType.yyy, "yyy"); return licenseTypes; } public static string GetById(int id) { var q = (from p in this.GetAll() where p.Key == id select p).Single(); return q.Value; } } 

3- Set the ViewBag in your controller

 var licenseTypes = LicenseTypeEnumService.GetAll(); ViewBag.LicenseTypes = new SelectList(licenseTypes, "Key", "Value"); 

4- Bind your DropDownList

 @Html.DropDownList("LicenseType", (SelectList)ViewBag.LicenseTypes) 

Here a Martin Faartoft variation where you can put custom labels which is nice for localization.

 public static class EnumHtmlHelper { public static SelectList ToSelectList<TEnum>(this TEnum enumObj, Dictionary<int, string> customLabels) where TEnum : struct, IComparable, IFormattable, IConvertible { var values = from TEnum e in Enum.GetValues(typeof(TEnum)) select new { Id = e, Name = customLabels.First(x => x.Key == Convert.ToInt32(e)).Value.ToString() }; return new SelectList(values, "Id", "Name", enumObj); } } 

Use in view:

 @Html.DropDownListFor(m => m.Category, Model.Category.ToSelectList(new Dictionary<int, string>() { { 1, ContactResStrings.FeedbackCategory }, { 2, ContactResStrings.ComplainCategory }, { 3, ContactResStrings.CommentCategory }, { 4, ContactResStrings.OtherCategory } }), new { @class = "form-control" }) @Html.ValidationMessageFor(m => m.Category)