我创建了一个默认的MVC 3项目(使用剃刀),以演示一个问题。
@Html.TextBoxFor(m => m.UserName)
如果我改变为:
@Html.TextBoxFor(m => m.UserName,new { title = "ABC" })
<input data-val="true" data-val-required="The User name field is required." id="UserName" name="UserName" title="ABC" type="text" value="" />
但是,如果我做一个EditorFor:
@Html.EditorFor(m => m.UserName,new { title = "ABC" })
<input class="text-Box single-line" data-val="true" data-val-required="The User name field is required." id="UserName" name="UserName" type="text" value="" />
所以总的来说,当我使用EditorFor时,title属性会丢失。
我知道TextBoxFor的第二个参数被称为htmlAttributes,而对于EditorFor它是additionalViewData,但我已经看到了EditorFor可以渲染这个参数提供的属性的例子。
任何人都可以解释我做错了,我怎么能有一个title属性使用EditorFor?
解决方法
我想我找到一个更好的解决方案。 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; }
public static MvcHtmlString RenderHtmlAttributes<TModel>(this HtmlHelper<TModel> htmlHelper,property.GetValue(htmlAttributes)); } } } return MvcHtmlString.Create(String.Join(" ",attributes.Keys.Select(key => String.Format("{0}=\"{1}\"",key,htmlHelper.Encode(attributes[key]))))); }