18

我正在尝试更新本教程,以将 Facebooks BigPipe 实施到剃须刀。

有一个 html 帮助器扩展,可将 pagelet 添加到列表中,然后将保存的 div 输出到响应中。这个想法是稍后这个 pagelet 的内容被呈现为一个字符串,然后通过 javascript 注入到这个持有的 div 中。

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>

它将 pagelet 添加到列表中,并将保存的 div 输出到响应流。

所以

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

但是,当我在 Razor 中尝试相同的操作时:

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

div 占位符出现在正文的顶部,在 textHolder div 之外。为什么是这样?我怎样才能让它表现得像在 div 内输出响应的 webforms 视图?

谢谢。

4

4 回答 4

42

Razor 视图由内向外渲染。基本上,它将内容写入临时缓冲区,当到达最顶部的布局页面时,这些缓冲区将写入响应流。因此,从您的 HtmlHelper 扩展直接写入响应流,将无序输出。

解决方案是使用:

helper.ViewContext.Writer.Write("<div id=\"" + pagelet.Container + "\"></div>");
于 2011-04-10T12:56:42.903 回答
4

将您的方法更改为不无效,但返回 MvcHtmlString

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

比以前那样使用它

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

Idea 受到以下事实的启发:MVC 中几乎每个输入(和其他)扩展方法都返回MvcHtmlString

于 2011-04-10T10:22:40.770 回答
0

您应该使用 ViewBag 并将字符串放入其中,然后将其输出。

在控制器中:

ViewBag.Foo = Bar;

鉴于:

<div>
@ViewBag.Foo
</div>
于 2011-04-10T10:11:20.577 回答
-4

我不会费心去做。你想要的最终结果是没有FooBar写在你的div,那么为什么不把它写到你的 div 中呢?为什么需要使用Response.Write

于 2011-04-10T10:09:08.677 回答