@jgauffin의 수락 된 답변을 기반으로 EnumDropDownListFor
항목 선택 문제를 다루는 자체 버전을 만들었습니다 .
문제는 여기 에 다른 SO 답변에 자세히 설명되어 있으며 기본적으로 .NET의 다양한 과부하 동작에 대한 오해로 인한 것입니다 DropDownList
.
내 전체 코드 ( htmlAttributes
등에 대한 오버로드 포함) 는 다음과 같습니다.
public static class EnumDropDownListForHelper
{
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression
) where TModel : class
{
return EnumDropDownListFor<TModel, TProperty>(
htmlHelper, expression, null, null);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
object htmlAttributes
) where TModel : class
{
return EnumDropDownListFor<TModel, TProperty>(
htmlHelper, expression, null, htmlAttributes);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IDictionary<string, object> htmlAttributes
) where TModel : class
{
return EnumDropDownListFor<TModel, TProperty>(
htmlHelper, expression, null, htmlAttributes);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
string optionLabel
) where TModel : class
{
return EnumDropDownListFor<TModel, TProperty>(
htmlHelper, expression, optionLabel, null);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
string optionLabel,
IDictionary<string,object> htmlAttributes
) where TModel : class
{
string inputName = GetInputName(expression);
return htmlHelper.DropDownList(
inputName, ToSelectList(typeof(TProperty)),
optionLabel, htmlAttributes);
}
public static MvcHtmlString EnumDropDownListFor<TModel, TProperty>(
this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
string optionLabel,
object htmlAttributes
) where TModel : class
{
string inputName = GetInputName(expression);
return htmlHelper.DropDownList(
inputName, ToSelectList(typeof(TProperty)),
optionLabel, htmlAttributes);
}
private static string GetInputName<TModel, TProperty>(
Expression<Func<TModel, TProperty>> expression)
{
if (expression.Body.NodeType == ExpressionType.Call)
{
MethodCallExpression methodCallExpression
= (MethodCallExpression)expression.Body;
string name = GetInputName(methodCallExpression);
return name.Substring(expression.Parameters[0].Name.Length + 1);
}
return expression.Body.ToString()
.Substring(expression.Parameters[0].Name.Length + 1);
}
private static string GetInputName(MethodCallExpression expression)
{
MethodCallExpression methodCallExpression
= expression.Object as MethodCallExpression;
if (methodCallExpression != null)
{
return GetInputName(methodCallExpression);
}
return expression.Object.ToString();
}
private static SelectList ToSelectList(Type enumType)
{
List<SelectListItem> items = new List<SelectListItem>();
foreach (var item in Enum.GetValues(enumType))
{
FieldInfo fi = enumType.GetField(item.ToString());
var attribute = fi.GetCustomAttributes(
typeof(DescriptionAttribute), true)
.FirstOrDefault();
var title = attribute == null ? item.ToString()
: ((DescriptionAttribute)attribute).Description;
var listItem = new SelectListItem
{
Value = item.ToString(),
Text = title,
};
items.Add(listItem);
}
return new SelectList(items, "Value", "Text");
}
}
여기 내 블로그 에이 글을 올렸습니다 .