ASP.NET Response Filter для переформатирования вывода вывода страниц ASPX? - PullRequest
2 голосов
/ 10 октября 2009

Я создал простой 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 НЕ вызывала запись несколько раз, например изменив размер буфера или я выбрал неправильный подход полностью, используя этот метод Response.Filter для манипулирования отображаемым выводом?

Ответы [ 4 ]

2 голосов
/ 10 октября 2009

Я бы просто буферизировал данные в методе 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)

2 голосов
/ 10 октября 2009

Руководствуясь статьей, предложенной Дарином Димитровым, я закончил следующей реализацией метода 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-кода перед выполнением фактической манипуляции строк в отображаемом выводе.

1 голос
/ 10 октября 2009

Может потребоваться проверить тип содержимого перед подключением фильтра ответов:

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

Есть также хорошая статья , описывающая фильтры ответов в ASP.NET.

0 голосов
/ 12 июня 2014

Ответ PropellerHead основан на нахождении закрывающего тега html в конечном буфере, но на самом деле конечный буфер слишком мал для размещения всего тега.

Более безопасный (и более эффективный) метод состоит в том, чтобы добавлять только в Write, а затем выполнять строковые операции и выводить в Close.

...