使用自定义HTML扩展在ASP.NET MVC 3 Razor View引擎中渲染损坏

DSO*_*DSO 4 asp.net-mvc razor

我刚刚安装了ASP.NET MVC 3 RC来尝试升级MVC 2站点.我遇到了一个渲染问题,我设法在网站之外重新编写,使用从头创建的MVC 3项目.

这是我的Razor cshtml视图:

@using Mvc3RCTest.Helpers

<h2>Demo Render Bug</h2>

<div class="content">
@{ Html.RenderTest(); }
</div>
Run Code Online (Sandbox Code Playgroud)

RenderTest是一个HTML扩展,定义如下:

using System.Web;
using System.Web.Mvc;

namespace Mvc3RCTest.Helpers
{
    public static class TestHtmlExtensions
    {
        public static void RenderTest(this HtmlHelper html)
        {
            HttpResponseBase r = html.ViewContext.HttpContext.Response;
            r.Write("<ul>");
            for (int i = 0; i < 10; ++i)
            {
                r.Write("<li>" + i + "</li>");
            }
            r.Write("</ul>");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

呈现时,HTML如下所示:

<ul><li>0</li><li>1</li><li>2</li><li>3</li><li>4</li><li>5</li><li>6</li><li>7</li><li>8</li><li>9</li></ul>
<h2>Demo Render Bug</h2>

<div class="content">
</div>
Run Code Online (Sandbox Code Playgroud)

如您所见,RenderTest HTML扩展的输出在Razor模板的其余部分之前被错误地发出.好像Razor渲染引擎试图缓存整个输出,而不知道HTML扩展可以直接写入输出.

有没有人见过这个问题?任何人都知道如何解决这个问题,而不必重做我的所有HTML扩展而不是直接写入输出?

mar*_*ind 9

不幸的是,你的助手应该写入ViewContext.Writer,像这样

public static void RenderTest(this HtmlHelper html)
{
    var writer = html.ViewContext.Writer;
    writer.Write("<ul>");
    for (int i = 0; i < 10; ++i)
    {
        writer.Write("<li>" + i + "</li>");
    }
    writer.Write("</ul>");
}
Run Code Online (Sandbox Code Playgroud)

在aspx视图引擎中,事情可能对你有用,但这纯属巧合.这并不是说Razor本身就是在缓存任何东西.由于Razor页面由内而外呈现,它会将内容写入临时缓冲区,而临时缓冲区只有在您到达最顶层布局页面时才会在适当的时间写入响应流.如果您直接写入响应流,那么您将不按顺序编写内容.