So che sono in ritardo alla festa su questo, ma ho pensato che potresti trovare utile questa variante, poiché questa ti consente anche di utilizzare stringhe descrittive piuttosto che costanti di enumerazione nel menu a discesa. A tale scopo, decorare ogni voce di enumerazione con un attributo [System.ComponentModel.Description].
Per esempio:
public enum TestEnum
{
[Description("Full test")]
FullTest,
[Description("Incomplete or partial test")]
PartialTest,
[Description("No test performed")]
None
}
Ecco il mio codice:
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);
}
Puoi quindi farlo a tuo avviso:
@Html.EnumDropDownListFor(model => model.MyEnumProperty)
Spero che questo ti aiuti!
** MODIFICA 2014-GEN-23: Microsoft ha appena rilasciato MVC 5.1, che ora ha una funzione EnumDropDownListFor. Purtroppo non sembra rispettare l'attributo [Descrizione] quindi il codice sopra rimane valido. Vedi la sezione Enum in note di rilascio di Microsoft per MVC 5.1.
Aggiornamento: tuttavia supporta l' attributo Display[Display(Name = "Sample")]
, quindi è possibile utilizzarlo.
[Aggiornamento - l'ho appena notato, e il codice sembra una versione estesa del codice qui: https://blogs.msdn.microsoft.com/stuartleeks/2010/05/21/asp-net-mvc-creating-a- dropdownlist-helper-for-enums / , con un paio di aggiunte. In tal caso, l'attribuzione sembrerebbe giusta ;-)]