使用自定义HTML扩展渲染腐败ASP.NET MVC 3的Razor视图引擎 [英] Rendering corruption in ASP.NET MVC 3 Razor View Engine Using Custom HTML Extension

查看:106
本文介绍了使用自定义HTML扩展渲染腐败ASP.NET MVC 3的Razor视图引擎的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚安装ASP.NET MVC 3 RC尝试和升级MVC 2的网站。我遇到我设法在站点之外瑞普渲染问题,用从零开始创建一个MVC 3项目。

下面是我的剃刀CSHTML观点:

  @using Mvc3RCTest.Helpers< H2>演示渲染的Bug< / H>< D​​IV CLASS =内容>
@ {Html.RenderTest(); }
< / DIV>

RenderTest是定义的HTML扩展如下:

 使用的System.Web;
使用System.Web.Mvc;命名空间Mvc3RCTest.Helpers
{
    公共静态类TestHtmlExtensions
    {
        公共静态无效RenderTest(此的HtmlHelper HTML)
        {
            HTT presponseBase R = html.ViewContext.HttpContext.Response;
            r.Write(&所述; UL>中);
            对(INT I = 0; I&小于10 ++ⅰ)
            {
                r.Write(<立GT;+ I +< /李>);
            }
            r.Write(&下; / UL>中);
        }
    }
}

在此呈现,在HTML如下所示:

<$p$p><$c$c><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>
&LT; H2&GT;演示渲染的Bug&LT; / H&GT;&LT; D​​IV CLASS =内容&GT;
&LT; / DIV&GT;

正如你所看到的,RenderTest HTML扩展的输出被错误地发出的的剃刀模板的其余部分。看来好象剃刀渲染引擎试图缓存整个输出,并没有意识到该HTML扩展可以直接写入到输出

有其他人看到这个问题?任何人都知道如何解决这个问题,而无需重做我所有的HTML扩展不是直接写入到输出?


解决方案

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

 公共静态无效RenderTest(此的HtmlHelper HTML)
{
    VAR作家= html.ViewContext.Writer;
    writer.Write(&所述; UL&gt;中);
    对(INT I = 0; I&小于10 ++ⅰ)
    {
        writer.Write(&LT;立GT;+ I +&LT; /李&GT;);
    }
    writer.Write(&下; / UL&gt;中);
}

东西可能会在ASPX视图引擎已经为你服务,然而这是纯属巧合。这并不是说剃刀缓存东西本身。由于剃刀页面内而外呈现它写的东西反过来只有当你到达最顶部的布局页面适当的时候被写入到响应流临时缓冲区。如果直接写入响应流,那么你将写的东西坏了。

I just installed ASP.NET MVC 3 RC to try and upgrade an MVC 2 site. I encountered a rendering problem which I managed to repro outside of the site, using an MVC 3 project created from scratch.

Here is my Razor cshtml view:

@using Mvc3RCTest.Helpers

<h2>Demo Render Bug</h2>

<div class="content">
@{ Html.RenderTest(); }
</div>

RenderTest is an HTML extension defined as follows:

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>");
        }
    }
}

When this is rendered, the HTML looks like the following:

<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>

As you can see, the output of the RenderTest HTML extension was incorrectly emitted before the rest of the Razor template. It seems as if the Razor rendering engine is trying to cache the entire output, without being aware that HTML extensions can write directly to the output.

Has anyone else seen this problem? Anyone know how to work around this, without having to redo all of my HTML extensions not to write directly to the output?

解决方案

Unfortunately, all of your helpers should be writing to the ViewContext.Writer, like so

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>");
}

Things might have worked for you in the aspx view engine, however that was purely coincidental. It's not that Razor is caching anything per se. Due to the inside-out rendering of Razor pages it writes things to temporary buffers which in turn get written to the response stream at the appropriate time only when you reach the top most layout page. If you write directly to the response stream then you will write things out of order.

这篇关于使用自定义HTML扩展渲染腐败ASP.NET MVC 3的Razor视图引擎的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆