问题描述
||
为了演示问题,我创建了一个默认的MVC 3项目(使用剃刀)。
在登录页面上,有一行:
@Html.TextBoxFor(m => m.UserName)
如果我将其更改为:
@Html.TextBoxFor(m => m.UserName,new { title = \"ABC\" })
然后将其呈现为(具有title属性):
<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\" })
然后将其呈现为(没有title属性)为:
<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可以呈现此参数提供的属性。
谁能解释我在做什么错,以及在使用EditorFor时如何拥有title属性?
解决方法
我想我找到了一个更好的解决方案。 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,property.GetValue(htmlAttributes));
}
}
}
return MvcHtmlString.Create(String.Join(\" \",attributes.Keys.Select(key =>
String.Format(\"{0}=\\\"{1}\\\"\",key,htmlHelper.Encode(attributes[key])))));
}
, 如果您创建自定义EditorFor模板,则可以使用这种解决方法在MVC3中添加标题(和其他htmlAttributes)。这种情况下,该值是可选的,并且对于editor不要求调用包含“ 9”
@Html.EditorFor(m => m.UserName,\"CustomTemplate\",new { title = \"ABC\" })
EditorTemplates / CustomTemplate.cshtml
@{
string s = \"\";
if (ViewData[\"title\"] != null) {
// The ViewData[\"name\"] is the name of the property in the addtionalViewData...
s = ViewData[\"title\"].ToString();
}
}
@Html.TextBox(\"\",new { title = s })
我做了非常相似的事情,在EditorTemplate中包含了一个可选类。您可以根据需要将任意多个项目添加到addtionalViewData中,但需要在EditorFor模板中进行处理。
, 您可以看一下以下博客文章,该文章说明了如何实现自定义元数据提供程序并在视图模型上使用数据批注以定义html属性(例如class
,maxlength
,title
,...)。与模板化的助手一起使用。