ASP.Net MVC 3 Razor Response.Write position

2019-03-17 19:35发布

I am trying to update this tutorial on implementing Facebooks BigPipe to razor.

There is a html helper extension that adds a pagelet to a list, and then outputs a holding div to the response. The idea is that later on the content of this pagelet is rendered to a string, and then injected into this holding div via 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>");
}

In the example this function is called like this:

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

Which adds the pagelet to the lists, and outputs the holding div to the response stream.

So

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

However, when I try the same in Razor:

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

The div placeholder appears at the top of the body, outside the textHolder div. Why is this? How can I get this to behave like the webforms view where the response is output inside the div?

Thanks.

4条回答
Juvenile、少年°
2楼-- · 2019-03-17 19:39

I wouldn't bother doing it. The end result you want is t have FooBar written within your div, so why not just write it into your div? Why do you need to use Response.Write?

查看更多
趁早两清
3楼-- · 2019-03-17 19:45

A Razor view is rendered inside-out. Basically it writes content to temporary buffers which get written to the response stream when the top most layout page is reached. Thus, writing directly to the response stream from your HtmlHelper extension, will output it out of order.

The solution is to use:

helper.ViewContext.Writer.Write("<div id=\"" + pagelet.Container + "\"></div>");
查看更多
女痞
4楼-- · 2019-03-17 19:51

You should use the ViewBag and put the string in there, then output it.

In controller:

ViewBag.Foo = Bar;

In view:

<div>
@ViewBag.Foo
</div>
查看更多
地球回转人心会变
5楼-- · 2019-03-17 19:55

Change your method to be not void, but returning MvcHtmlString

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

Than use this as you used to

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

Idea is inspired by the fact that almost every input(and other) extension method in MVC returns MvcHtmlString

查看更多
登录 后发表回答