我一直在为MVC 5网站做一个扩展方法。其基本思想是它将为我们的输入组创建标记(即放入标签,输入和验证消息)。这些组将具有一些标准的HTML和CSS类,这些类将始终存在。到目前为止,这是我所拥有的,而且工作正常。如何使用EditorFor在MVC 5中添加动态HTML属性?
public static MvcHtmlString CreateEditorForGroup<TModel, TProperty>(this HtmlHelper<TModel> helper,
Expression<Func<TModel, TProperty>> expression)
{
TagBuilder editorLabel = new TagBuilder("span");
editorLabel.AddCssClass("form-label");
editorLabel.InnerHtml += helper.LabelFor(expression);
TagBuilder wrappingDiv = new TagBuilder("div");
wrappingDiv.InnerHtml = editorLabel.ToString() + helper.EditorFor(expression, new { htmlAttributes = new { @class = "form-control" }}).ToString() + helper.ValidationMessageFor(expression).ToString();
return new MvcHtmlString(wrappingDiv.ToString());
}
我还需要扩展一下,以允许传递额外的自定义HTML属性(额外的CSS类,数据属性等)。所以,我能走到今天:
public static MvcHtmlString CreateEditorForGroup<TModel, TProperty>(this HtmlHelper<TModel> helper,
Expression<Func<TModel, TProperty>> expression, object htmlAttributesForEditor = null)
{
TagBuilder editorLabel = new TagBuilder("span");
editorLabel.AddCssClass("form-label");
editorLabel.InnerHtml += helper.LabelFor(expression);
var editorHtmlAttributes = MergeHtmlAttributes(htmlAttributesForEditor, new { @class = "form-control" });
TagBuilder wrappingDiv = new TagBuilder("div");
wrappingDiv.InnerHtml = editorLabel.ToString() + helper.EditorFor(expression, new { htmlAttributes = editorHtmlAttributes }).ToString() + helper.ValidationMessageFor(expression);
return new MvcHtmlString(wrappingDiv.ToString());
}
(不要担心MergeHtmlAttributes
的定义目前,它工作正常,返回IDictionary<string, object>
)由于所有我做过的研究(和我自己的测试)表明,我可以请执行下列操作
helper.EditorFor(expression, new { htmlAttributes = new { @class = "form-control" }})
,并得到预期的结果(在我的情况下,与CSS类“的形式控制”文本框)。但是,如果我使用合并属性的代码,那么与没有第二个参数调用EditorFor
(即,我的文本框在未设置任何CSS类时出现)相比,我没有任何不同。
所以我尝试了一些其他的东西,比如将合并后的属性投射到object
。不用找了。我试图将合并的属性转换为ExpandoObject
。没有。在传入之前试图将ExpandoObject
转换为object
。没有区别。
有没有办法做到这一点?这似乎很奇怪,这只适用于匿名类型,而大多数其他方法(TextBoxFor
等)可以采用属性字典。
(我可以在此时想到的唯一的事情就是开始重写/覆盖默认模板以某种方式适应这一点。如果我没有我宁愿不走这一步。)
为什么一个RouteValueDictionary有所作为?这与路由根本没有关系。 – Becuzz
https://cpratt.co/html-editorfor-and-htmlattributes/ – RitchieD
如果你阅读那篇文章,它指出,在MVC 5.1中,他们通过增加使用匿名对象的能力来解决我遇到的问题使用它。有了这个修复,他们碰巧使用了一个RouteValueDictionary(正如文章所承认的,一旦它的用途扩大,它就成了一个可怕的名字)。但从MVC 5开始,实现这一目标的唯一方法是覆盖默认模板。因此,您的解决方案实际上并未解决MVC 5中的问题。在这种情况下,“解决方案”将升级到MVC 5.1或更高版本。 – Becuzz