ASP.NET 响应过滤器重新格式化 ASPX 页面的渲染输出?

发布于 2024-08-07 12:57:08 字数 814 浏览 5 评论 0原文

我创建了一个简单的 HttpModule 和响应流来重新格式化网页的渲染输出(请参阅下面的代码片段)。

在 HttpModule 中,我将 Response.Filter 设置为我的 PageStream:

m_Application.Context.Response.Filter = new PageStream(m_Application.Context);

在 PageStream 中,我覆盖 Write 方法,以便重新格式化呈现的输出:

public override void Write(byte[] buffer, int offset, int count)
{
    string html = System.Text.Encoding.UTF8.GetString(buffer);
    //Do some string resplace operations here...
    byte[] input = System.Text.Encoding.UTF8.GetBytes(html);
    m_DefaultStream.Write(input, 0, input.Length);
}

在简单的 HTML 页面 (.html) 上使用它时,此方法工作正常,但是当我在 ASPX 页 (.aspx) 上使用此方法,多次调用 Write 方法,将重新格式化分为不同的步骤,并可能破坏字符串替换操作。

我该如何解决这个问题?有没有办法让 ASPX 页面不调用 Write 多次,例如通过更改其缓冲区大小,或者我是否完全选择了错误的方法,通过使用此 Response.Filter 方法来操纵渲染的输出?

I've created a simple HttpModule and response stream to reformat the rendered output of web pages (see code snippets below).

In the HttpModule I set the Response.Filter to my PageStream:

m_Application.Context.Response.Filter = new PageStream(m_Application.Context);

In the PageStream I overwrite the Write method in order to do my reformatting of the rendered output:

public override void Write(byte[] buffer, int offset, int count)
{
    string html = System.Text.Encoding.UTF8.GetString(buffer);
    //Do some string resplace operations here...
    byte[] input = System.Text.Encoding.UTF8.GetBytes(html);
    m_DefaultStream.Write(input, 0, input.Length);
}

And this work fine when using it on simple HTML pages (.html), but when I use this method on ASPX pages (.aspx), the Write method is called several times, splitting up the reformatting into different steps, and potentially destroying the string replacement operations.

How do I solve this? Is there a way to let the ASPX page NOT call Write several times, e.g. by changing its buffer size, or have I chosen the wrong approach entirely, by using this Response.Filter method to manipulate the rendered output?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

鸠书 2024-08-14 12:57:08

我只是在 Write 方法中缓冲数据,并在 Close 方法中执行字符串操作,如下所示:(

private readonly Stream _forwardStream;
private readonly StringBuilder _sb;

// snip

public override void Write (byte[] buffer, int offset, int count)
{
  string chunk = Encoding.UTF8.GetString (buffer, offset, count);
  _sb.Append (chunk);
}

public override void Close ()
{
  string result = GetManipulatedString ();

  byte[] rawResult = Encoding.UTF8.GetBytes (result);
  _forwardStream.Write (rawResult, 0, rawResult.Length);

  base.Close ();
  _forwardStream.Close ();
}

如果您在 MemoryStream 中收集数据,可能会更好)

I would just buffer the data in the Write method, and do the string operations in the Close method, like this:

private readonly Stream _forwardStream;
private readonly StringBuilder _sb;

// snip

public override void Write (byte[] buffer, int offset, int count)
{
  string chunk = Encoding.UTF8.GetString (buffer, offset, count);
  _sb.Append (chunk);
}

public override void Close ()
{
  string result = GetManipulatedString ();

  byte[] rawResult = Encoding.UTF8.GetBytes (result);
  _forwardStream.Write (rawResult, 0, rawResult.Length);

  base.Close ();
  _forwardStream.Close ();
}

(Maybe even better if you collect the data in a MemoryStream)

风和你 2024-08-14 12:57:08

在 Darin Dimitrov 建议的文章的指导下,我最终实现了 Write 方法的以下实现,该方法也适用于 ASPX 页面:

public override void Write(byte[] buffer, int offset, int count)
{
    string strBuffer = System.Text.UTF8Encoding.UTF8.GetString (buffer, offset, count);

    if (!strBuffer.Contains("</html>"))
    {
        m_ResponseHtml.Append(strBuffer);
    }
    else
    {
        m_ResponseHtml.Append(strBuffer);
        string  html = m_ResponseHtml.ToString ();

        //Do some string operations here...
        byte[] input = System.Text.Encoding.UTF8.GetBytes(html);
        m_DefaultStream.Write(input, 0, input.Length);           
    }
}

该代码利用 StringBuilder (m_ResponseHtml) 来累积整个 HTML,然后再对渲染的内容进行实际的字符串操作输出。

Guided by the article suggested by Darin Dimitrov, I ended with the following implementation of the Write method that also works perfectly with ASPX pages:

public override void Write(byte[] buffer, int offset, int count)
{
    string strBuffer = System.Text.UTF8Encoding.UTF8.GetString (buffer, offset, count);

    if (!strBuffer.Contains("</html>"))
    {
        m_ResponseHtml.Append(strBuffer);
    }
    else
    {
        m_ResponseHtml.Append(strBuffer);
        string  html = m_ResponseHtml.ToString ();

        //Do some string operations here...
        byte[] input = System.Text.Encoding.UTF8.GetBytes(html);
        m_DefaultStream.Write(input, 0, input.Length);           
    }
}

The code leverages a StringBuilder (m_ResponseHtml) to accumulate the entire HTML, before doing the actual string manupulation on the rendered output.

与风相奔跑 2024-08-14 12:57:08

您可能需要在附加响应过滤器之前检查内容类型:

var response = m_Application.Context.Response;
if (response.ContentType == "text/html")
{
    response.Filter = new PageStream(m_Application.Context);
}

还有一篇很好的 文章 描述了ASP.NET 中的响应过滤器。

You might need to check the content type before attaching the response filter:

var response = m_Application.Context.Response;
if (response.ContentType == "text/html")
{
    response.Filter = new PageStream(m_Application.Context);
}

There's also a nice article describing response filters in ASP.NET.

我的影子我的梦 2024-08-14 12:57:08

PropellerHead 的响应依赖于在最终缓冲区中查找结束 html 标记,但实际上我让最终缓冲区太小而无法包含整个标记。

更安全(也更高效)的方法是只在 Write 中进行追加,然后在 Close 中进行字符串操作和输出。

PropellerHead's response relies on finding the closing html tag in the final buffer, but I actually had the final buffer be too small to contain the entire tag.

A safer (and more efficient as well) method is to only do the append in Write and to then do the string operations and output in Close.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文