Как мога да превърна анонимен обект в двойки ключ/стойност или 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 и получих приблизително същото количество код.


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

person Justin Morgan    schedule 29.02.2012
comment
Вашата версия обаче е XSS уязвимост. Използвайте TagBuilder; не изобретявайте отново колелото. - person SLaks; 29.02.2012
comment
@Slaks - имам контрол върху стойностите, влизащи в HTML, и те са ограничен набор от стойности, които не идват от потребителски вход. Разбира се, все пак. - person Justin Morgan; 01.03.2012
comment
Намерих този отговор за полезен при изграждането на сложни компоненти, където не контролирате целия си HTML. - person Rubens Mariuzzo; 10.03.2013