ASP.Net MVC 3 Razor Response.Записать позицию - PullRequest
19 голосов
/ 10 апреля 2011

Я пытаюсь обновить это руководство по внедрению BigPipe в Facebook для бритвы.

Существует расширение html-помощника, которое добавляет листлет в список, а затем выводит в ответ удерживающий div. Идея состоит в том, что позже содержимое этого постлета будет преобразовано в строку, а затем введено в этот элемент div с помощью JavaScript.

public static void RegisterPagelet(this HtmlHelper helper, Pagelet pagelet) {
    var context = helper.ViewContext.HttpContext;
    List<Pagelet> pagelets = (List<Pagelet>)context.Items["Pagelets"];
    if (pagelets == null) {
        pagelets = new List<Pagelet>();
        context.Items["Pagelets"] = pagelets;
    }
    pagelets.Add(pagelet);
    context.Response.Write("<div id=\"" + pagelet.Container + "\"></div>");
}

В примере эта функция вызывается так:

<div id="textHolder">
    <% Html.RegisterPagelet(myPagelet); %>
</div>

Который добавляет страницу в списки и выводит удерживающий div в поток ответов.

Итак

<div id="textHolder">
    <div id="pageletPlaceHolder"></div>
</div>

Однако, когда я пытаюсь сделать то же самое в Razor:

<div id="textHolder">
    @{ Html.RegisterPagelet(myPagelet);  }
</div>

Заполнитель div отображается в верхней части тела, за пределами div textHolder. Почему это? Как я могу заставить это вести себя как представление webforms, где ответ выводится внутри div?

Спасибо.

Ответы [ 4 ]

42 голосов
/ 10 апреля 2011

Вид Razor отображается наизнанку.По сути, он записывает содержимое во временные буферы, которые записываются в поток ответов при достижении самой верхней страницы макета.Таким образом, запись непосредственно в поток ответов из вашего расширения HtmlHelper выведет его не по порядку.

Решение заключается в использовании:

helper.ViewContext.Writer.Write("<div id=\"" + pagelet.Container + "\"></div>");
4 голосов
/ 10 апреля 2011

Измените ваш метод, чтобы он не был пустым, а возвращал MvcHtmlString

public static MvcHtmlString OutputText(this HtmlHelper helper, string text) {
     return New MvcHtmlString(text);
}

Чем использовать это, как вы привыкли

<div id="textHolder">
    @Html.OutputText("FooBar");
</div>

Идея вдохновлена ​​тем фактом, что почти каждый метод расширения ввода (и другие) в MVC возвращает MvcHtmlString

0 голосов
/ 10 апреля 2011

Вы должны использовать ViewBag и поместить туда строку, а затем вывести ее.

В контроллере:

ViewBag.Foo = Bar;

В представлении:

<div>
@ViewBag.Foo
</div>
0 голосов
/ 10 апреля 2011

Я бы не стал этого делать.Конечный результат, который вы хотите, - это FooBar, записанный в вашем div, так почему бы просто не записать его в свой div?Зачем вам нужно использовать Response.Write?

...