如何使用EditorFor在MVC 5中添加动态HTML属性

本文关键字:添加 动态 HTML 属性 何使用 EditorFor MVC | 更新日期: 2023-09-27 18:14:07

我一直在为MVC 5站点制作一个扩展方法。其基本思想是,它将为我们的输入组创建标记(即,放入标签、输入和验证消息中(。这些组将具有一些标准的HTML和CSS类,这些类将始终存在。到目前为止,这就是我所拥有的,而且运行良好。

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类"form control"的文本框(。但是,如果我使用合并属性的代码,我不会得到任何不同于在没有第二个参数的情况下调用EditorFor的代码(即,我的文本框没有设置任何CSS类(。

因此,我尝试了其他一些方法,比如将合并后的属性强制转换为object。没有变化。我尝试将合并的属性转换为ExpandoObject。没有什么在传入之前尝试将ExpandoObject强制转换为object。没有区别。

有办法做到这一点吗?奇怪的是,这只适用于匿名类型,而大多数其他方法(TextBoxFor等(都可以使用属性字典。

(在这一点上,我唯一能想到的就是开始重写/覆盖默认模板,以适应这种情况。如果没有必要,我宁愿不走这条路。(

如何使用EditorFor在MVC 5中添加动态HTML属性

我认为您需要将htmlAttributes从匿名更改为RouteValueDictionary

试试这样的东西:

RouteValueDictionary htmlAttributes = HtmlHelper.AnonymousObjectToHtmlAttributes(editorHtmlAttributes);
... + helper.EditorFor(expression, new { htmlAttributes = htmlAttributes }).ToString() + ...