Добавление HtmlAttributes в шаблон

Если я передаю HtmlAttributes в шаблон, например:

@Html.DisplayFor(m => m.FirstName, new { htmlAttributes = new { @class = "orangetxt strongtxt" } })

в моем шаблоне, как бы я вставил их в свой HTML:

<span @ViewData["htmlAttributes"]>@Model</span>

Это почти работает, но он делает некоторые довольно странные вещи, поэтому я предполагаю, что это не путь.

Я понимаю, что могу выполнить это с помощью метода расширения HtmlHelper, чтобы отобразить полный HTML-элемент (в данном случае span) и передать атрибуты таким образом, но есть ли способ просто отобразить атрибуты прямо в элемент HTML, как в приведенном выше примере?

4 ответов


приведенный ниже метод расширения позволит мне преобразовать HtmlAttributes в строку:

    public static MvcHtmlString RenderHtmlAttributes<TModel>(
        this HtmlHelper<TModel> htmlHelper, object htmlAttributes)
    {
        var attrbituesDictionary = new RouteValueDictionary(htmlAttributes);

        return MvcHtmlString.Create(String.Join(" ", 
            attrbituesDictionary.Select(
                item => String.Format("{0}=\"{1}\"", item.Key, 
                htmlHelper.Encode(item.Value)))));
    }

затем, чтобы отобразить их в теге, я могу просто сделать это:

<span @Html.RenderHtmlAttributes(ViewData["htmlAttributes"])>@Model</span>

ответ Джерада Роуза хорош, но я столкнулся с парой проблем с ним:

  • он не преобразует подчеркивания в тире в именах атрибутов
  • он не обрабатывает атрибуты без значения изящно

чтобы решить первую проблему, используйте HtmlHelper.AnonymousObjectToHtmlAttributes.

Ниже приведена моя модификация метода Джерада:

public static MvcHtmlString RenderHtmlAttributes(this HtmlHelper helper, object htmlAttributes)
{
        if (htmlAttributes == null) return new MvcHtmlString(String.Empty);
        var attrbituesDictionary = HtmlHelper.AnonymousObjectToHtmlAttributes(htmlAttributes);
        return new MvcHtmlString(String.Join(" ", attrbituesDictionary.Select(item => string.IsNullOrEmpty((string)item.Value) ? String.Format("{0}", item.Key) : String.Format("{0}=\"{1}\"", item.Key, helper.Encode(item.Value)))));
}

попробуйте это вместо

@Html.DisplayFor(m => m.FirstName, 
                 new { htmlAttributes = "class = orangetxt strongtxt"})

Это будет отображать строку, в то время как ваша версия делала странные вещи, оказанные { } как часть производства.


DisplayFor() используется для отображения шаблона, соответствующего типу свойства.

шаблоны отображения .cshtml-файлы внутри /DisplayTemplates папка, которая, в свою очередь, находится внутри папки просмотра (т. е. любой папки из дома, общего или даже конкретного контроллера).

пример.

если у вас строку.cshtml по шаблон, как это внутри /Вид/Общая:

@model String

@if (string.IsNullOrEmpty(Model)) {
   <span>(no string)</span>
}
else {
   <span>@Model</span>
}

каждый раз, когда вы называете DisplayFor() для строкового свойства:

DisplayFor(model => model.MyStringProperty);

он отображает шаблон в соответствии со значением строки. Вы можете быть более конкретным и поставить /DisplayTemplates внутри определенной папки представления и их только вызовы из этих представлений зависят от шаблона.


в вашем случае вы можете быть еще более конкретным и называют DisplayFor() С определенным шаблоном.

Предположим, у вас есть шаблон для определенного свойства, называется MyPropertyTemplate.cshtml по. Вы бы позвонили DisplayFor() такой:

DisplayFor(model => model.MyProperty, "MyPropertyTemplate");

и их, внутри этого шаблона вы можете иметь любые атрибуты HTML, которые вы хотите.

@model MyProperty

<span class="orangetxt strongtxt">@MyProperty.ToString()</span>

PS: когда он не находит шаблон, я думаю, что он вызывает только model.Property.ToString() без дополнительного html.

FYI:EditorFor(), например, работает аналогичным образом, но использует /EditorTemplates.