我想我找到了一个更好的解决方案。 EditorFor 接受 AdditionalViewData 作为参数。如果你给它一个名为“htmlAttributes”的参数和属性,那么我们可以用它做一些有趣的事情:
@Html.EditorFor(model => model.EmailAddress,
new { htmlAttributes = new { @class = "span4",
maxlength = 128,
required = true,
placeholder = "Email Address",
title = "A valid email address is required (i.e. user@domain.com)" } })
在模板(在本例中为 EmailAddress.cshtml)中,您可以提供一些默认属性:
@Html.TextBox("",
ViewData.TemplateInfo.FormattedModelValue,
Html.MergeHtmlAttributes(new { type = "email" }))
魔法通过这个辅助方法聚集在一起:
public static IDictionary<string, object> MergeHtmlAttributes<TModel>(this HtmlHelper<TModel> htmlHelper, object htmlAttributes)
{
var attributes = htmlHelper.ViewData.ContainsKey("htmlAttributes")
? HtmlHelper.AnonymousObjectToHtmlAttributes(htmlHelper.ViewData["htmlAttributes"])
: new RouteValueDictionary();
if (htmlAttributes != null)
{
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(htmlAttributes))
{
var key = property.Name.Replace('_', '-');
if (!attributes.ContainsKey(key))
{
attributes.Add(key, property.GetValue(htmlAttributes));
}
}
}
return attributes;
}
当然,如果您使用的是原始 HTML,您也可以修改它以呈现属性:
public static MvcHtmlString RenderHtmlAttributes<TModel>(this HtmlHelper<TModel> htmlHelper, object htmlAttributes)
{
var attributes = htmlHelper.ViewData.ContainsKey("htmlAttributes")
? HtmlHelper.AnonymousObjectToHtmlAttributes(htmlHelper.ViewData["htmlAttributes"])
: new RouteValueDictionary();
if (htmlAttributes != null)
{
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(htmlAttributes))
{
var key = property.Name.Replace('_', '-');
if (!attributes.ContainsKey(key))
{
attributes.Add(key, property.GetValue(htmlAttributes));
}
}
}
return MvcHtmlString.Create(String.Join(" ",
attributes.Keys.Select(key =>
String.Format("{0}=\"{1}\"", key, htmlHelper.Encode(attributes[key])))));
}