2009-10-10 4 views
2

Я создал простой поток HttpModule и ответ, чтобы переформатировать выводимый вывод веб-страниц (см. Ниже фрагменты кода).Фильтр ответов ASP.NET для преобразования выводимого вывода ASPX-страниц?

В HttpModule я установить Response.Filter моему PageStream:

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

В PageStream я перезаписать метод записи для того, чтобы сделать мою переформатирование воспроизведенной выходной:

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 для управления выводимым результатом?

ответ

2

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

Th e code использует StringBuilder (m_ResponseHtml), чтобы накапливать весь HTML, прежде чем выполнять фактическую manupulation строки на отображаемом выходе.

1

Вам может понадобиться, чтобы проверить тип содержимого перед установкой фильтра ответ:

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

Там также хороший article описания фильтров ответа в ASP.NET.

+0

Хотя ваш ответ не имеет никакого смысла по отношению к моему вопросу, я, естественно, проверяю тип содержимого перед установкой Response.Filter, предоставленная статья мне помогла. Благодарю. – PropellerHead

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)

0

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^