Я работал над созданием метода расширения для сайта MVC 5. Основная идея заключается в том, что она создаст разметку для наших групп ввода (т. Е. Помещает метки, входы и сообщения проверки). Эти группы будут иметь стандартные классы HTML и CSS, которые всегда будут присутствовать. Пока это то, что у меня есть, и он работает нормально.Как добавить динамические атрибуты HTML в MVC 5 с помощью редактора?
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