Enumdropdownlist用于扩展描述和短名称字段

时间:2017-06-19 19:17:52

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

MVC的EnumDropDownListFor html帮助器不呈现Description和ShortName属性。我需要为渲染的选项标签定制属性文本。我搜索了很多不是为了重写MVC中的所有东西,但我找不到任何东西。

我知道除了WebForms之外,MVC是非常不同的,但MVC应该提供了一种自定义renderin机制的方法。

1 个答案:

答案 0 :(得分:0)

根据我的搜索,我首先需要读取Enum类型的所有成员,然后重写包含验证的renderering机制。修改基本方法的最糟糕的选择是使用正则表达式。 结果代码如下所示:

    public static MvcHtmlString EnumDropDownListForEx<T, TProperty>(this HtmlHelper<T> htmlHelper, Expression<Func<T, TProperty>> expression, 
        object htmlAttributes, string placeholder = "")
    {
        var type = Nullable.GetUnderlyingType(typeof(TProperty)) ?? typeof(TProperty);
        var values = Enum.GetValues(type);

        var name = ExpressionHelper.GetExpressionText(expression);
        var fullHtmlFieldName = htmlHelper.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(name);

        var select = new TagBuilder("select");
        select.MergeAttribute("name", fullHtmlFieldName);
        select.MergeAttributes(new RouteValueDictionary(htmlAttributes));

        var option = new TagBuilder("option");
        option.MergeAttribute("value", "");
        option.MergeAttribute("selected", "selected");
        option.InnerHtml = placeholder;

        var sb = new StringBuilder();
        sb.Append(option.ToString(TagRenderMode.Normal));

        foreach (Enum value in values)
        {
            option = new TagBuilder("option");
            option.MergeAttribute("value", value.ToInt().ToString());
            option.InnerHtml = value.GetEnumDescription();

            var attr = value.GetAttribute<DisplayAttribute>();
            if(attr == null)
                continue;

            option.InnerHtml = attr.Name;
            option.MergeAttribute("description", attr.Description);
            option.MergeAttribute("shortname", attr.ShortName);
            sb.Append(option.ToString(TagRenderMode.Normal));
        }

        select.InnerHtml = sb.ToString();
        select.MergeAttributes(htmlHelper.GetUnobtrusiveValidationAttributes(name));

        return MvcHtmlString.Create(select.ToString(TagRenderMode.Normal));
    }