MVC html helper动态生成枚举下拉列表

时间:2017-05-01 14:15:02

标签: asp.net-mvc razor html-helper

我的模特是:

public class DynamicEnum
{
    public string Name {get; set;}
    public int Value {get; set;}
}

public class ViewModel
{
    public DynamicEnum DynamicEnum {get; set;}
}

Public ActionResult MyAction
{
    var model = new ViewModel();
    model.DynamicEnum = new DynamicEnum(){ Name = "System.DayOfWeek", Value = 2};
    return View(model);
}

所以在视图中我需要一个HtmlHelper来动态生成DropDownListFor,如:

@Html.EnumDropDownListFor(m => m.DynamicEnum)

我使用过MVC 5.2.3,有没有人有任何想法?

1 个答案:

答案 0 :(得分:1)

实现这一目标的一种方法是使用反射:

public static class HtmlExtensions
{
    public static IHtmlString EnumDropDownListFor<TModel>(
        this HtmlHelper<TModel> html, 
        Expression<Func<TModel, DynamicEnum>> expression)
    {
        var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
        var dynamicEnum = (DynamicEnum)metadata.Model;
        var enumType = Type.GetType(dynamicEnum.Name, true);
        if (!enumType.IsEnum)
        {
            throw new Exception(dynamicEnum.Name + " doesn't represent a valid enum type");
        }

        // TODO: You definetely want to cache the values here to avoid the expensive
        // reflection call: a ConcurrentDictionary<Type, IList<SelectListItem>> could be used
        var enumNames = Enum.GetNames(enumType);
        var values = enumNames.Select(x => new SelectListItem
        {
            Text = x,
            Value = ((int)Enum.Parse(enumType, x)).ToString(),
        }).ToList();

        string name = ExpressionHelper.GetExpressionText(expression) + ".Value";

        return html.DropDownList(name, values);
    }
}

备注:ASP.NET MVC中已存在HtmlHelper.EnumDropDownListFor扩展方法,因此请确保将声明自定义扩展方法的命名空间放入范围以避免冲突。或者只使用不同的方法名称。