我怎么能在任何我想要的响应流中插入一个字符串?

时间:2010-05-07 19:19:11

标签: asp.net asp.net-mvc string httpmodule response.write

可能有一种简单的方法可以做到这一点,但我看不到它......

我创建了一个简单的Http模块,它在PreRequestHandler上启动一个计时器,并停止PostRequestHandler上的计时器,以计算页面加载所需的时间。

然后我创建一些简单的html并将我的结果写入Response.Write。由于我在PostRequestHandler中执行此操作,因此它会在</html>标记之后添加我的结果。这对测试很好,但我需要在页面需要验证的情况下。

我似乎无法弄清楚如何操作Response对象以在</body>标记之前插入我的结果。 Response.Write和Response.Output.Write没有这种灵活性,我无法看到使用Response作为字符串的方法。我错过了一些简单的东西吗?

1 个答案:

答案 0 :(得分:8)

为此,您必须实现自己的流对象,并将其用作响应的过滤器。

对于isntance:

public class TimerStream : Stream
{
    private Stream inner { get; set; }
    private StringBuilder   responseHtml;

    public TimerStream(Stream inputStream) { 
        inner = inputStream; 
        responseHtml = new StringBuilder();
        // Setup your timer
    }

    /* Filter overrides should pass through to inner, all but Write */
    public override void Write(byte[] buffer, int offset, int count)
    {
        string bufferedHtml = System.Text.UTF8Encoding.UTF8.GetString (buffer, offset, count);
        Regex endTag = new Regex ("</html>", RegexOptions.IgnoreCase);

        if (!endTag.IsMatch (bufferedHtml))
        {
            responseHtml.Append(bufferedHtml);
        }
        else
        {
            // insert timer html into buffer, then...
            responseHtml.Append (bufferedHtml);
            byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes (responseHtml.ToString ());            
            inner.Write (data, 0, data.Length);            
        }
    }
}

然后,在你的HttpModule中,你将它添加到你的BeginRequest:

// Change the Stream filter
HttpResponse response = context.Response;
response.Filter = new TimerStream(context.Response.Filter);