2009-10-10 50 views
2

我已經創建了一個簡單的HttpModule和響應流來重新格式化網頁的渲染輸出(請參閱下面的代碼片段)。ASP.NET響應篩選以重新格式化ASPX頁面的呈現輸出?

在我的Response.Filter設置爲我PageStream的HTTP模塊:

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

在我重寫Write方法,以盡我的渲染輸出的重新格式化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頁面無法多次寫入,例如通過改變它的緩衝區大小,或者我完全選擇了錯誤的方法,通過使用這個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);   
    } 
} 

釷e代碼利用StringBuilder(m_ResponseHtml)累積整個HTML,然後在呈現的輸出上進行實際的字符串處理。

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 2009-10-10 10:28:19

2

我只想緩衝區寫入方法的數據,並在關閉方法做字符串操作,像這樣:

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中執行字符串操作和輸出。