Как превратить анонимный объект в пары ключ/значение или атрибуты HTML?

В моем приложении MVC у меня есть вспомогательный класс, предназначенный для отображения группы связанных кнопок. Я пытаюсь передать атрибуты HTML кнопок как анонимный объект:

new { @class="myClass1 myClass2" }

Помощник выдает HTML как MvcHtmlString, который я сейчас строю следующим образом:

        foreach (var b in _buttons)
        {
            sb.AppendFormat("<button type='submit' name='{0}' {1}>{2}</button>",
                b.Value,
                b.HtmlAttributes,
                b.Text);
        }

Моя проблема в том, что приведенный выше код создает недопустимый HTML:

<button type='submit' name='Foo' { class = myClass1 myClass2 }>Bar</button>

К сожалению, поскольку он передается помощнику как object, у меня нет информации о типе для работы. Я мог бы ToString объект и проанализировать результат, но это выглядит довольно глупо. Как я могу программно преобразовать анонимный объект в атрибуты HTML в стиле key="value"? Существует ли существующая утилита для этого?


person Justin Morgan    schedule 29.02.2012    source источник


Ответы (2)


Вы должны использовать класс TagBuilder, который создает HTML-теги для вас.

Затем вы можете написать

builder.MergeAttributes(HtmlHelper.AnonymousObjectToHtmlAttributes(HtmlAttributes));
person SLaks    schedule 29.02.2012
comment
Я не использовал TagBuilder в своей окончательной версии, но спасибо, что сообщили мне, что он существует. +1. - person Justin Morgan; 29.02.2012
comment
Обновление: это не тот метод, который я использовал, но это потому, что мой случай был несколько уникальным. TagBuilder - лучшая практика, поэтому я принимаю этот ответ. - person Justin Morgan; 30.03.2012
comment
Любой эквивалент для веб-форм ASP.NET? - person Rubens Mariuzzo; 25.06.2013
comment
@RubensMariuzzo: вы можете ссылаться на System.Web.Mvc.dll из проекта WebForms и использовать этот класс. - person SLaks; 26.06.2013

Как оказалось, для этого в классе HtmlHelper есть статический метод:

HtmlHelper.AnonymousObjectToHtmlAttributes(b.HtmlAttributes)

Это решило мою проблему:

    foreach (var b in _buttons)
    {
        var dict = HtmlHelper.AnonymousObjectToHtmlAttributes(b.HtmlAttributes);

        var attr = dict.Keys.Zip(
            dict.Values, 
            (k, v) => string.Format("{0}='{1}'", k, v));

        sb.AppendFormat("<button type='submit' name='{0}' {1}>{2}</button>",
            b.Value,
            string.Join(" ", attr),
            b.Text);
    }

Я также попробовал это с помощью TagBuilder и получил примерно такое же количество кода.


Редактировать: Как указал Слакс, такой способ является потенциальной XSS-уязвимостью. В моем конкретном случае не было никакого риска, но TagBuilder кажется лучшей практикой.

person Justin Morgan    schedule 29.02.2012
comment
Однако ваша версия является XSS-уязвимостью. Используйте 1_; не изобретайте велосипед. - person SLaks; 29.02.2012
comment
@Slaks - я контролирую значения, входящие в HTML, и они представляют собой ограниченный набор значений, которые не поступают из пользовательского ввода. Тем не менее, точка взята. - person Justin Morgan; 01.03.2012
comment
Я нашел этот ответ полезным при создании сложных компонентов, где вы не полностью контролируете свой HTML. - person Rubens Mariuzzo; 10.03.2013