2

Webページのレンダリングされた出力を再フォーマットするための単純な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メソッドを使用してレンダリングされた出力を操作することにより、間違ったアプローチを完全に選択しましたか?

4

4 に答える 4

2

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にデータを収集するとさらに良いかもしれません)

于 2009-10-10T09:42:29.250 に答える
2

Darin Dimitrov によって提案された記事に導かれて、私は ASPX ページでも完全に機能する Write メソッドの次の実装で終了しました。

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 全体を蓄積します。

于 2009-10-10T10:22:47.343 に答える
1

応答フィルターをアタッチする前に、コンテンツ タイプを確認する必要がある場合があります。

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

ASP.NETの応答フィルターについて説明した素晴らしい記事もあります。

于 2009-10-10T08:35:47.380 に答える
0

PropellerHead の応答は、最終バッファーで終了 HTML タグを見つけることに依存していますが、実際には、最終バッファーが小さすぎてタグ全体を含めることができませんでした。

より安全な (そしてより効率的な) 方法は、Write で追加のみを行い、次に文字列操作と出力を Close で行うことです。

于 2014-06-12T15:21:07.333 に答える