2016-10-20 6 views
1

Я работал над созданием метода расширения для сайта 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 и т. Д.) Могут принимать словарь атрибутов.

(Единственное, что я могу думать в этот момент, чтобы начать перезапись/переопределение шаблонов по умолчанию, чтобы учесть это как-то. Я бы предпочел не идти по этому пути, если я не должен.)

ответ

0

Я думаю, что вам нужно изменить htmlAttributes от анонимного RouteValueDictionary

Попробуйте что-то вроде этого:

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

Почему бы RouteValueDictionary сделать разницу? Это не имеет никакого отношения к маршрутизации вообще. – Becuzz

+0

https://cpratt.co/html-editorfor-and-htmlattributes/ – RitchieD

+0

Если вы прочитали эту статью, в ней указано, что в MVC 5.1 они исправили проблему, с которой я столкнулся, добавив возможность использовать анонимный объект так, как я был используй это. С этим исправлением им пришлось использовать RouteValueDictionary (который, как признается в статье, является ужасным именем после того, как его использование расширилось). Но с MVC 5 единственным способом добиться этого было переопределение шаблонов по умолчанию. Поэтому ваше решение на самом деле не устраняет проблему в MVC 5. «Решение» в этом случае будет состоять в том, чтобы перейти на MVC 5.1 или выше. – Becuzz