.net中自定义过滤器对Response内容进行处理
生活随笔
收集整理的這篇文章主要介紹了
.net中自定义过滤器对Response内容进行处理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原文:http://www.cnblogs.com/zgqys1980/archive/2008/09/02/1281895.html
代碼DEMO:http://files.cnblogs.com/peaceli/httpModuleTest.rar
因項目需要,對每一個訪問網站的請求要做原始數據記錄,其中要包括幾個要素:
1.客戶端的IP
2.客戶端請求的頁面路徑
3.客戶端發出的請求頭
4.服務器返回的正文內容。
在代碼設計前分析了一下,前三個都很好解決,對于截獲服務器返回的正文,準備用HttpResponse 對象中的Output 和 OutputStream 屬性輸出信息來解決。
可是在正式編碼的過程中,發現Output和OutputStream 并不是想像中可以直接把數據轉出取回,耗費了近兩天的時間,想盡了一切辦法可還是僅僅可以追加內容并無法讀取。
在網上查閱到,對于HttpResponse 對象,僅僅可以使用過濾器來對其中將要輸出的內容進行修改。
這個過濾器要繼承自Stream 類,并要實現其中的虛方法??磥碇捌髨D使用HttpWriter,TextWriter,Stream,HttpStream 這些類來轉出數據完全是錯誤的。
現在有信心來截獲服務器返回內容了,說干就干吧!
1.首先要建立一個簡易過濾器。
代碼如下:
using?System;
using?System.Collections.Generic;
using?System.Text;
using?System.Text.RegularExpressions;
using?System.IO;
using?System.Web;
? ??/**////
<summary>
? ??///?定義原始數據EventArgs,便于在截獲完整數據后,由事件傳遞數據
? ??///
</summary>
public
class?RawDataEventArgs : EventArgs
? ??{
? ?? ???private
string?sourceCode;
? ?? ???public?RawDataEventArgs(string?SourceCode)
? ?? ???{
? ?? ?? ?? ?sourceCode?=?SourceCode;
? ?? ???}
? ?? ???public
string?SourceCode
? ?? ???{
? ?? ?? ?? ?get
{?return?sourceCode; }
? ?? ?? ?? ?set
{ sourceCode?=?value; }
? ?? ???}
? ? }
//自定義過濾器
? ??public
class?RawFilter : Stream
? ??{
? ?? ???Stream responseStream;
? ?? ???long?position;
? ?? ???StringBuilder responseHtml;
? ?? ???/**////
<summary>
? ?? ???///?當原始數據采集成功后激發。
? ?? ???///
</summary>
public
event?EventHandler<RawDataEventArgs>?OnRawDataRecordedEvent;
? ?? ???public?RawFilter(Stream inputStream)
? ?? ???{
? ?? ?? ?? ?responseStream?=?inputStream;
? ?? ?? ?? ?responseHtml?=
new?StringBuilder();
? ?? ???}
//實現Stream 虛方法
Filter Overrides#region?Filter Overrides
? ?? ???public
override
bool?CanRead
? ?? ???{
? ?? ?? ?? ?get
? ?? ?? ?? ?{
? ?? ?? ?? ?? ??return
true;
? ?? ?? ?? ?}
? ?? ???}
? ?? ???public
override
bool?CanSeek
? ?? ???{
? ?? ?? ?? ?get
? ?? ?? ?? ?{
? ?? ?? ?? ?? ??return
true;
? ?? ?? ?? ?}
? ?? ???}
? ?? ???public
override
bool?CanWrite
? ?? ???{
? ?? ?? ?? ?get
? ?? ?? ?? ?{
? ?? ?? ?? ?? ??return
true;
? ?? ?? ?? ?}
? ?? ???}
? ?? ???public
override
void?Close()
? ?? ???{
? ?? ?? ?? ?responseStream.Close();
? ?? ???}
? ?? ???public
override
void?Flush()
? ?? ???{
? ?? ?? ?? ?responseStream.Flush();
? ?? ???}
? ?? ???public
override
long?Length
? ?? ???{
? ?? ?? ?? ?get
? ?? ?? ?? ?{
? ?? ?? ?? ?? ??return
0;
? ?? ?? ?? ?}
? ?? ???}
? ?? ???public
override
long?Position
? ?? ???{
? ?? ?? ?? ?get
? ?? ?? ?? ?{
? ?? ?? ?? ?? ??return?position;
? ?? ?? ?? ?}
? ?? ?? ?? ?set
? ?? ?? ?? ?{
? ?? ?? ?? ?? ? position?=?value;
? ?? ?? ?? ?}
? ?? ???}
? ?? ???public
override
int?Read(byte[] buffer,?int?offset,?int?count)
? ?? ???{
? ?? ?? ?? ?return?responseStream.Read(buffer, offset, count);
? ?? ???}
? ?? ???public
override
long?Seek(long?offset, SeekOrigin origin)
? ?? ???{
? ?? ?? ?? ?return?responseStream.Seek(offset, origin);
? ?? ???}
? ?? ???public
override
void?SetLength(long?length)
? ?? ???{
? ?? ?? ?? ?responseStream.SetLength(length);
? ?? ???}
? ?? ???#endregion
//關鍵的點,在HttpResponse 輸入內容的時候,一定會調用此方法輸入數據,所以要在此方法內截獲數據
public
override
void?Write(byte[] buffer,?int?offset,?int?count)
? ?? ???{
? ?? ?? ?? ?string?strBuffer?=?System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);
//采用正則,檢查輸入的是否有頁面結束符</html>
? ?? ?? ?? ?Regex eof?=
new?Regex("</html>", RegexOptions.IgnoreCase);
? ?? ?? ?? ?if?(!eof.IsMatch(strBuffer))
? ?? ?? ?? ?{
? ?? ?? ?? ???//頁面沒有輸出完畢,繼續追加內容
? ?? ?? ?? ?? ? responseHtml.Append(strBuffer);
? ?? ?? ?? ?}
? ?? ?? ?? ?else
? ?? ?? ?? ?{
? ?? ?? ?? ???//頁面輸出已經完畢,截獲內容
? ?? ?? ?? ?? ? responseHtml.Append(strBuffer);
? ?? ?? ?? ?? ??string?finalHtml?=?responseHtml.ToString();
? ?? ?? ?? ?//激發數據已經獲取事件
? ?? ?? ?? ?OnRawDataRecordedEvent(this,?new?RawDataEventArgs(finalHtml));
? ?? ?? ?? ?? ??//繼續傳遞要發出的內容寫入流
byte[] data?=?System.Text.UTF8Encoding.UTF8.GetBytes(finalHtml);
? ?? ?? ?? ?? ? responseStream.Write(data,?0, data.Length);
? ?? ?? ?? ?}
? ?? ???}
? ? }
至此,過濾器定義完畢了,接下來還需要把這個過濾器裝配到HttpResponse 對象中。
為了能夠截獲整站的aspx 頁面輸出的內容,我們可以定義一個HttpModule 來完成。
代碼如下:
using?System;
using?System.Web;
using?System.Collections.Generic;
using?System.Text;
using?System.IO;
using?System.Diagnostics;
? ??public
class?HttpRawDataModule : IHttpModule
? ??{
? ?? ???IHttpModule 成員#region?IHttpModule 成員
? ?? ???public
void?Dispose()
? ?? ???{
? ?? ???}
? ?? ???public
void?Init(HttpApplication context)
? ?? ???{
? ?? ?? ?? ?//綁定事件,在對此請求處理過程全部結束后進行過濾操作
? ?? ?? ?? ?context.ReleaseRequestState?+=
new?EventHandler(context_ReleaseRequestState);
? ?? ???}
? ?? ???#endregion
? ?? ???/**////
<summary>
? ?? ???///?對此HTTP請求處理的過程全部結束
? ?? ???///
</summary>
? ?? ???///
<param name="sender"></param>
? ?? ???///
<param name="e"></param>
void?context_ReleaseRequestState(object?sender, EventArgs e)
? ?? ???{
? ?? ?? ?? ?HttpApplication application?=?(HttpApplication)sender;
? ?? ?? ?? ?//這里需要針對ASPX頁面進行攔截,測試發現如果不這么做,Wap 訪問站點圖片容易顯示為X,奇怪
string[] temp?=?application.Request.CurrentExecutionFilePath.Split('.');
? ?? ?? ?? ?if?(temp.Length?>
0
&&?temp[temp.Length?-
1].ToLower()?==
"aspx")
? ?? ?? ?? ?{
? ?? ?? ?? ?? ??//裝配過濾器
? ?? ?? ?? ?? ? application.Response.Filter?=
new?RawFilter(application.Response.Filter);
? ?? ?? ?? ?? ??//綁定過濾器事件
? ?? ?? ?? ?? ? RawFilter filter?=?(RawFilter)application.Response.Filter;
? ?? ?? ?? ?? ? filter.OnRawDataRecordedEvent?+=
new?EventHandler<RawDataEventArgs>(filter_OnRawDataRecordedEvent);
? ?? ?? ?? ?}
? ?? ???}
? ?? ???/**////
<summary>
? ?? ???///?當原始數據采集到以后,入庫?
? ?? ???///
</summary>
? ?? ???///
<param name="sender"></param>
? ?? ???///
<param name="e"></param>
void?filter_OnRawDataRecordedEvent(object?sender, RawDataEventArgs e)
? ?? ???{
? ?? ?? ?? ?string?allcode?=?e.SourceCode;
? ?? ?? ?? ?WapSite.SiteDataClass wapdata?=
new?WapSite.SiteDataClass();
? ?? ?? ?? ?wapdata.WriteRawDataLog(allcode);
? ?? ???}
? ? }
HttpModule 準備完畢,也裝配上了過濾器,接下來還需要在配置文件中配置HttpModules配置節 ,把自定義的HttpModule 加入到HTTP處理管道中。
在Web.config 中增加配置節如下:
<system.web>
? ??<httpModules>
? ?? ?<add?name="RawDataModule"?type="HttpRawDataModule"/>
? ??</httpModules>
??</system.web>
測試成功,能準確的獲得服務器向客戶端輸出的HTML內容。
其中,在過濾器中,可以直接對即將要輸出的內容做 對于字符串的任意處理。
而且采用這樣的方式來對站點即將輸出的內容做修改和采集,可以通過修改配置文件,隨時打開和關閉,有很強的優越性和靈活性還有重用性。
記得看到過很多需要產生靜態頁面的網站,都是通過代碼HttpWebRequest 向自己請求并記錄返回的代碼產生靜態頁面,不知道我當前介紹的方法是否更好寫,比如需要產生靜態頁面時,不管是誰發出請求,由服務器檢查自己是否有靜態頁面,否則產生靜態頁面,并轉向。給出引子,希望大家還是自己開闊思路比較好。
代碼DEMO:http://files.cnblogs.com/peaceli/httpModuleTest.rar
因項目需要,對每一個訪問網站的請求要做原始數據記錄,其中要包括幾個要素:
1.客戶端的IP
2.客戶端請求的頁面路徑
3.客戶端發出的請求頭
4.服務器返回的正文內容。
在代碼設計前分析了一下,前三個都很好解決,對于截獲服務器返回的正文,準備用HttpResponse 對象中的Output 和 OutputStream 屬性輸出信息來解決。
可是在正式編碼的過程中,發現Output和OutputStream 并不是想像中可以直接把數據轉出取回,耗費了近兩天的時間,想盡了一切辦法可還是僅僅可以追加內容并無法讀取。
在網上查閱到,對于HttpResponse 對象,僅僅可以使用過濾器來對其中將要輸出的內容進行修改。
這個過濾器要繼承自Stream 類,并要實現其中的虛方法??磥碇捌髨D使用HttpWriter,TextWriter,Stream,HttpStream 這些類來轉出數據完全是錯誤的。
現在有信心來截獲服務器返回內容了,說干就干吧!
1.首先要建立一個簡易過濾器。
代碼如下:
using?System;
using?System.Collections.Generic;
using?System.Text;
using?System.Text.RegularExpressions;
using?System.IO;
using?System.Web;
? ??/**////
<summary>
? ??///?定義原始數據EventArgs,便于在截獲完整數據后,由事件傳遞數據
? ??///
</summary>
public
class?RawDataEventArgs : EventArgs
? ??{
? ?? ???private
string?sourceCode;
? ?? ???public?RawDataEventArgs(string?SourceCode)
? ?? ???{
? ?? ?? ?? ?sourceCode?=?SourceCode;
? ?? ???}
? ?? ???public
string?SourceCode
? ?? ???{
? ?? ?? ?? ?get
{?return?sourceCode; }
? ?? ?? ?? ?set
{ sourceCode?=?value; }
? ?? ???}
? ? }
//自定義過濾器
? ??public
class?RawFilter : Stream
? ??{
? ?? ???Stream responseStream;
? ?? ???long?position;
? ?? ???StringBuilder responseHtml;
? ?? ???/**////
<summary>
? ?? ???///?當原始數據采集成功后激發。
? ?? ???///
</summary>
public
event?EventHandler<RawDataEventArgs>?OnRawDataRecordedEvent;
? ?? ???public?RawFilter(Stream inputStream)
? ?? ???{
? ?? ?? ?? ?responseStream?=?inputStream;
? ?? ?? ?? ?responseHtml?=
new?StringBuilder();
? ?? ???}
//實現Stream 虛方法
Filter Overrides#region?Filter Overrides
? ?? ???public
override
bool?CanRead
? ?? ???{
? ?? ?? ?? ?get
? ?? ?? ?? ?{
? ?? ?? ?? ?? ??return
true;
? ?? ?? ?? ?}
? ?? ???}
? ?? ???public
override
bool?CanSeek
? ?? ???{
? ?? ?? ?? ?get
? ?? ?? ?? ?{
? ?? ?? ?? ?? ??return
true;
? ?? ?? ?? ?}
? ?? ???}
? ?? ???public
override
bool?CanWrite
? ?? ???{
? ?? ?? ?? ?get
? ?? ?? ?? ?{
? ?? ?? ?? ?? ??return
true;
? ?? ?? ?? ?}
? ?? ???}
? ?? ???public
override
void?Close()
? ?? ???{
? ?? ?? ?? ?responseStream.Close();
? ?? ???}
? ?? ???public
override
void?Flush()
? ?? ???{
? ?? ?? ?? ?responseStream.Flush();
? ?? ???}
? ?? ???public
override
long?Length
? ?? ???{
? ?? ?? ?? ?get
? ?? ?? ?? ?{
? ?? ?? ?? ?? ??return
0;
? ?? ?? ?? ?}
? ?? ???}
? ?? ???public
override
long?Position
? ?? ???{
? ?? ?? ?? ?get
? ?? ?? ?? ?{
? ?? ?? ?? ?? ??return?position;
? ?? ?? ?? ?}
? ?? ?? ?? ?set
? ?? ?? ?? ?{
? ?? ?? ?? ?? ? position?=?value;
? ?? ?? ?? ?}
? ?? ???}
? ?? ???public
override
int?Read(byte[] buffer,?int?offset,?int?count)
? ?? ???{
? ?? ?? ?? ?return?responseStream.Read(buffer, offset, count);
? ?? ???}
? ?? ???public
override
long?Seek(long?offset, SeekOrigin origin)
? ?? ???{
? ?? ?? ?? ?return?responseStream.Seek(offset, origin);
? ?? ???}
? ?? ???public
override
void?SetLength(long?length)
? ?? ???{
? ?? ?? ?? ?responseStream.SetLength(length);
? ?? ???}
? ?? ???#endregion
//關鍵的點,在HttpResponse 輸入內容的時候,一定會調用此方法輸入數據,所以要在此方法內截獲數據
public
override
void?Write(byte[] buffer,?int?offset,?int?count)
? ?? ???{
? ?? ?? ?? ?string?strBuffer?=?System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);
//采用正則,檢查輸入的是否有頁面結束符</html>
? ?? ?? ?? ?Regex eof?=
new?Regex("</html>", RegexOptions.IgnoreCase);
? ?? ?? ?? ?if?(!eof.IsMatch(strBuffer))
? ?? ?? ?? ?{
? ?? ?? ?? ???//頁面沒有輸出完畢,繼續追加內容
? ?? ?? ?? ?? ? responseHtml.Append(strBuffer);
? ?? ?? ?? ?}
? ?? ?? ?? ?else
? ?? ?? ?? ?{
? ?? ?? ?? ???//頁面輸出已經完畢,截獲內容
? ?? ?? ?? ?? ? responseHtml.Append(strBuffer);
? ?? ?? ?? ?? ??string?finalHtml?=?responseHtml.ToString();
? ?? ?? ?? ?//激發數據已經獲取事件
? ?? ?? ?? ?OnRawDataRecordedEvent(this,?new?RawDataEventArgs(finalHtml));
? ?? ?? ?? ?? ??//繼續傳遞要發出的內容寫入流
byte[] data?=?System.Text.UTF8Encoding.UTF8.GetBytes(finalHtml);
? ?? ?? ?? ?? ? responseStream.Write(data,?0, data.Length);
? ?? ?? ?? ?}
? ?? ???}
? ? }
至此,過濾器定義完畢了,接下來還需要把這個過濾器裝配到HttpResponse 對象中。
為了能夠截獲整站的aspx 頁面輸出的內容,我們可以定義一個HttpModule 來完成。
代碼如下:
using?System;
using?System.Web;
using?System.Collections.Generic;
using?System.Text;
using?System.IO;
using?System.Diagnostics;
? ??public
class?HttpRawDataModule : IHttpModule
? ??{
? ?? ???IHttpModule 成員#region?IHttpModule 成員
? ?? ???public
void?Dispose()
? ?? ???{
? ?? ???}
? ?? ???public
void?Init(HttpApplication context)
? ?? ???{
? ?? ?? ?? ?//綁定事件,在對此請求處理過程全部結束后進行過濾操作
? ?? ?? ?? ?context.ReleaseRequestState?+=
new?EventHandler(context_ReleaseRequestState);
? ?? ???}
? ?? ???#endregion
? ?? ???/**////
<summary>
? ?? ???///?對此HTTP請求處理的過程全部結束
? ?? ???///
</summary>
? ?? ???///
<param name="sender"></param>
? ?? ???///
<param name="e"></param>
void?context_ReleaseRequestState(object?sender, EventArgs e)
? ?? ???{
? ?? ?? ?? ?HttpApplication application?=?(HttpApplication)sender;
? ?? ?? ?? ?//這里需要針對ASPX頁面進行攔截,測試發現如果不這么做,Wap 訪問站點圖片容易顯示為X,奇怪
string[] temp?=?application.Request.CurrentExecutionFilePath.Split('.');
? ?? ?? ?? ?if?(temp.Length?>
0
&&?temp[temp.Length?-
1].ToLower()?==
"aspx")
? ?? ?? ?? ?{
? ?? ?? ?? ?? ??//裝配過濾器
? ?? ?? ?? ?? ? application.Response.Filter?=
new?RawFilter(application.Response.Filter);
? ?? ?? ?? ?? ??//綁定過濾器事件
? ?? ?? ?? ?? ? RawFilter filter?=?(RawFilter)application.Response.Filter;
? ?? ?? ?? ?? ? filter.OnRawDataRecordedEvent?+=
new?EventHandler<RawDataEventArgs>(filter_OnRawDataRecordedEvent);
? ?? ?? ?? ?}
? ?? ???}
? ?? ???/**////
<summary>
? ?? ???///?當原始數據采集到以后,入庫?
? ?? ???///
</summary>
? ?? ???///
<param name="sender"></param>
? ?? ???///
<param name="e"></param>
void?filter_OnRawDataRecordedEvent(object?sender, RawDataEventArgs e)
? ?? ???{
? ?? ?? ?? ?string?allcode?=?e.SourceCode;
? ?? ?? ?? ?WapSite.SiteDataClass wapdata?=
new?WapSite.SiteDataClass();
? ?? ?? ?? ?wapdata.WriteRawDataLog(allcode);
? ?? ???}
? ? }
HttpModule 準備完畢,也裝配上了過濾器,接下來還需要在配置文件中配置HttpModules配置節 ,把自定義的HttpModule 加入到HTTP處理管道中。
在Web.config 中增加配置節如下:
<system.web>
? ??<httpModules>
? ?? ?<add?name="RawDataModule"?type="HttpRawDataModule"/>
? ??</httpModules>
??</system.web>
測試成功,能準確的獲得服務器向客戶端輸出的HTML內容。
其中,在過濾器中,可以直接對即將要輸出的內容做 對于字符串的任意處理。
而且采用這樣的方式來對站點即將輸出的內容做修改和采集,可以通過修改配置文件,隨時打開和關閉,有很強的優越性和靈活性還有重用性。
記得看到過很多需要產生靜態頁面的網站,都是通過代碼HttpWebRequest 向自己請求并記錄返回的代碼產生靜態頁面,不知道我當前介紹的方法是否更好寫,比如需要產生靜態頁面時,不管是誰發出請求,由服務器檢查自己是否有靜態頁面,否則產生靜態頁面,并轉向。給出引子,希望大家還是自己開闊思路比較好。
?.net中自定義過濾器對Response內容進行處理
總結
以上是生活随笔為你收集整理的.net中自定义过滤器对Response内容进行处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 开源视频会议bigbluebutton
- 下一篇: C#-datagriview的表头高度的