помощники не отображаются правильно

В настоящее время я нахожусь в процессе переноса своих представлений aspx mvc на движок бритвы, но я столкнулся с некоторой головной болью, когда дело доходит до моих помощников.

Я не уверен, почему, но мои помощники отображаются в виде текста, а не в виде разметки, когда я пытаюсь использовать помощника в его форме расширения html, я получаю текст, а не html.

Код для расширения:

    public static string LinkButton(this HtmlHelper helper, string id, string value, string target, object htmlAttributes)
    {
        var linkButton = new TagBuilder("div");
        var attributes = new RouteValueDictionary(htmlAttributes);

        linkButton.MergeAttribute("id", id);

        //-- apply the button class to the div and any other classes to the button
        linkButton.MergeAttribute("class", attributes.ContainsKey("class") ? string.Format("linkbutton {0}", attributes["class"]) : "linkbutton");

        var content = new TagBuilder("a");
        content.MergeAttribute("href", target);
        content.InnerHtml = value;

        linkButton.InnerHtml = content.ToString();
        return linkButton.ToString();
    }

Это довольно простое расширение, и оно используется следующим образом:

[ul]
    @foreach (UpModule module in ViewBag.Modules)
    {
        [li]@Html.LinkButton(module.Name, module.Value, module.Target, new {@class = "landingButton"});[/li]
    }
[/ul]

кроме явно неправильных html-тегов, что я напутал?

edit Я должен отметить, что там неправильная разметка, так как я не могу отобразить правильную разметку в своем вопросе, и я полностью осознаю, что это не сработает.


person Marqueone    schedule 21.01.2013    source источник
comment
Какой файл вы пишете? Я никогда не видел, чтобы [ul] употреблялся в чем-либо, кроме ‹ul›.   -  person Antarr Byrd    schedule 22.01.2013
comment
Вы уверены, что хотите, чтобы это была строка, а не MvcHtmlString?   -  person Pavel Voronin    schedule 22.01.2013
comment
@Antarr Byrd, разметка в моем коде правильная, у меня либо голова сломана, и я не могу заставить html-разметку правильно делать покупки, либо стек ненавидит меня прямо сейчас.   -  person Marqueone    schedule 22.01.2013
comment
@voroninp Это сработало отлично, но я не уверен, почему представление Razor требует от меня использования MvcHtmlString. Можете ли вы объяснить, поскольку я немного теряюсь в этом.   -  person Marqueone    schedule 22.01.2013
comment
@codejam Для защиты от атак с использованием межсайтовых сценариев (XSS) Razor кодирует любую строку как «безопасную для HTML». Но когда Razor видит MvcHtmlstring, он не кодирует его.   -  person Pavel Voronin    schedule 22.01.2013


Ответы (2)


Строки, возвращаемые в ваших шаблонах с помощью синтаксиса бритвы @, по умолчанию закодированы в HTML, чтобы не выводить HTML-разметку напрямую.

var s = "<p>text</p>";
....
@s

выведет что-то похожее на

&lt;p&gt;text&lt;/p&gt;

Чтобы предотвратить это, вы можете использовать метод HtmlHelpers Raw:

@Html.Raw(s)

Или вы можете использовать HtmlString (или до .NET 4, MvcHtmlString):

var s = new HtmlString("<p>text</p>");

Используя HtmlString (MvcHtmlString), бритва знает, что нельзя HTML-кодировать выходную строку.


Поэтому в вашем конкретном случае вы либо используете @Html.Raw(Html.LinkButton(...)), либо меняете тип вывода своего вспомогательного расширения:

public static HtmlString LinkButton(this HtmlHelper helper, string id, string value, string target, object htmlAttributes)
...
return new HtmlString(linkButton.ToString());
person marapet    schedule 21.01.2013

Однако @voroninp переключение типа возвращаемого значения со строки на MvcHtmlString работало отлично, в этом случае использование декларативного помощника является более четким вариантом, хотя переключение типа возвращаемого значения для моего более сложного помощника будет работать намного лучше.

person Marqueone    schedule 21.01.2013