为与模型绑定一起使用的输入创建我自己的HtmlHelper扩展

时间:2013-08-10 11:02:11

标签: asp.net-mvc html-helper mvc-editor-templates

我对当前的DropDownList实现感到不满意,因为我对选项标签没有太多帮助(只支持选中,支持文本和值)。我想在自己的位置设置残疾人和其他个人选项。

目前我正在通过javascript改变选项,但我认为这有点像hacky方式,而且我更愿意直接渲染正确的html。

我知道我可以创建一个使用select和option标签的模板,并根据需要制作选项 - 但是正常的DropDownList扩展添加了val的东西以及特定的名称和ID,我想这是为了在提交时正确的数据绑定形式:

<select data-val="true" data-val-number="The field SelectedValue must be a number." id="ParentDropDown_SelectedValue" name="ParentDropDown.SelectedValue">

如何将这些属性添加到我自己的模板中?

1 个答案:

答案 0 :(得分:28)

您是对的,这些属性(特别是名称属性)对于模型绑定至关重要。

假设您要创建一个自定义帮助器,如

public static MvcHtmlString CustomHelperFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)

首先,您可以使用var fieldName = ExpressionHelper.GetExpressionText(expression);获取字段名称。

然后使用var fullBindingName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName);获取全名,处理嵌套视图。

最后,您可以使用var fieldId = TagBuilder.CreateSanitizedId(fullBindingName);将其转换为id属性。

因此,创建文本框的简单自定义帮助程序可以写为:

public static MvcHtmlString CustomHelperFor<TModel, TValue>(this HtmlHelper<TModel> html, Expression<Func<TModel, TValue>> expression)
{            
    var fieldName = ExpressionHelper.GetExpressionText(expression);
    var fullBindingName = html.ViewContext.ViewData.TemplateInfo.GetFullHtmlFieldName(fieldName);
    var fieldId = TagBuilder.CreateSanitizedId(fullBindingName);

    var metadata = ModelMetadata.FromLambdaExpression(expression, html.ViewData);
    var value = metadata.Model;

    TagBuilder tag = new TagBuilder("input");
    tag.Attributes.Add("name", fullBindingName);
    tag.Attributes.Add("id", fieldId);
    tag.Attributes.Add("type", "text");
    tag.Attributes.Add("value", value == null ? "" : value.ToString());

    var validationAttributes = html.GetUnobtrusiveValidationAttributes(fullBindingName, metadata);
    foreach (var key in validationAttributes.Keys)
    {
        tag.Attributes.Add(key, validationAttributes[key].ToString());
    }

    return new MvcHtmlString(tag.ToString(TagRenderMode.SelfClosing));
}

您可以在以下视图中使用它:

@Html.CustomHelperFor(model => model.ParentDropDown.SelectedValue)

它将产生以下html:

<input id="ParentDropDown_SelectedValue" name="ParentDropDown.SelectedValue" type="text" value="4">

希望它有所帮助!