私は同じ問題を抱えていて、これらの拡張メソッドを作成しました:
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Linq.Expressions;
using System.Web.Mvc;
using System.Web.Mvc.Html;
public static class EnumHelper
{
private static readonly SelectListItem[] SingleEmptyItem = new[] { new SelectListItem { Text = string.Empty, Value = string.Empty } };
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression)
{
return htmlHelper.EnumDropDownListFor(expression, null);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TEnum>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TEnum>> expression, object htmlAttributes)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
var enumType = GetNonNullableModelType(metadata);
var values = Enum.GetValues(enumType).Cast<TEnum>();
var items =
values.Select(value => new SelectListItem
{
Text = GetName(value),
Value = value.ToString(),
Selected = value.Equals(metadata.Model)
});
if (metadata.IsNullableValueType)
{
items = SingleEmptyItem.Concat(items);
}
return htmlHelper.DropDownListFor(expression, items, htmlAttributes);
}
private static string GetName<TEnum>(TEnum value)
{
var displayAttribute = GetDisplayAttribute(value);
return displayAttribute == null ? value.ToString() : displayAttribute.GetName();
}
private static DisplayAttribute GetDisplayAttribute<TEnum>(TEnum value)
{
return value.GetType()
.GetField(value.ToString())
.GetCustomAttributes(typeof(DisplayAttribute), false)
.Cast<DisplayAttribute>()
.FirstOrDefault();
}
private static Type GetNonNullableModelType(ModelMetadata modelMetadata)
{
var realModelType = modelMetadata.ModelType;
var underlyingType = Nullable.GetUnderlyingType(realModelType);
return underlyingType ?? realModelType;
}
}
ビューでこれらの拡張メソッドを次のように使用できます。
@Html.EnumDropDownListFor(c=> comment.CommentType)
に応じて、列挙値の名前を含むドロップダウンリストが表示されるはずですDisplayAttribute
。
表示された列挙値の実際の取得は、GetName
メソッドで行われます。このメソッドは、最初にGetDisplayAttribute
メソッドを使用して列挙値の取得を試みDisplayAttribute
ます。列挙値が実際に で装飾されている場合はDisplayAttribute
、それを使用して表示する名前を取得します。がない場合DisplayAttribute
は、列挙値の名前を返すだけです。