.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 类,并要实现其中的虚方法。看来之前企图使用HttpWriter,TextWriter,Stream,HttpStream 这些类来转出数据完全是错误的。

现在有信心来截获服务器返回内容了,说干就干吧!

1.首先要建立一个简易过滤器。
代码如下:

.net中自定义过滤器对Response内容进行处理using System;
.net中自定义过滤器对Response内容进行处理
using System.Collections.Generic;
.net中自定义过滤器对Response内容进行处理
using System.Text;
.net中自定义过滤器对Response内容进行处理
using System.Text.RegularExpressions;
.net中自定义过滤器对Response内容进行处理
using System.IO;
.net中自定义过滤器对Response内容进行处理
using System.Web;
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理    
/**////
<summary>
.net中自定义过滤器对Response内容进行处理    
/// 定义原始数据EventArgs,便于在截获完整数据后,由事件传递数据
.net中自定义过滤器对Response内容进行处理    
///
</summary>

.net中自定义过滤器对Response内容进行处理
public
class RawDataEventArgs : EventArgs
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理    
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理        
private
string sourceCode;
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
public RawDataEventArgs(string SourceCode)
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            sourceCode 
= SourceCode;
.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理        
public
string SourceCode
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理            
get
.net中自定义过滤器对Response内容进行处理return sourceCode; }
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理            
set
.net中自定义过滤器对Response内容进行处理{ sourceCode = value; }
.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理    }

.net中自定义过滤器对Response内容进行处理
//自定义过滤器
.net中自定义过滤器对Response内容进行处理    
public
class RawFilter : Stream
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理    
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        Stream responseStream;
.net中自定义过滤器对Response内容进行处理        
long position;
.net中自定义过滤器对Response内容进行处理        StringBuilder responseHtml;
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
/**////
<summary>
.net中自定义过滤器对Response内容进行处理        
/// 当原始数据采集成功后激发。
.net中自定义过滤器对Response内容进行处理        
///
</summary>

.net中自定义过滤器对Response内容进行处理
public
event EventHandler<RawDataEventArgs> OnRawDataRecordedEvent;
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
public RawFilter(Stream inputStream)
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            responseStream 
= inputStream;
.net中自定义过滤器对Response内容进行处理            responseHtml 
=
new StringBuilder();
.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理
//实现Stream 虚方法
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理

Filter Overrides#region Filter Overrides
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
public
override
bool CanRead
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            
get
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理            
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理                
return
true;
.net中自定义过滤器对Response内容进行处理            }

.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
public
override
bool CanSeek
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            
get
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理            
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理                
return
true;
.net中自定义过滤器对Response内容进行处理            }

.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
public
override
bool CanWrite
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            
get
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理            
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理                
return
true;
.net中自定义过滤器对Response内容进行处理            }

.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理        
public
override
void Close()
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            responseStream.Close();
.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
public
override
void Flush()
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            responseStream.Flush();
.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
public
override
long Length
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            
get
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理            
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理                
return
0;
.net中自定义过滤器对Response内容进行处理            }

.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
public
override
long Position
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            
get
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理            
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理                
return position;
.net中自定义过滤器对Response内容进行处理            }

.net中自定义过滤器对Response内容进行处理            
set
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理            
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理                position 
= value;
.net中自定义过滤器对Response内容进行处理            }

.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
public
override
int Read(byte[] buffer, int offset, int count)
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            
return responseStream.Read(buffer, offset, count);
.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
public
override
long Seek(long offset, SeekOrigin origin)
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            
return responseStream.Seek(offset, origin);
.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
public
override
void SetLength(long length)
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            responseStream.SetLength(length);
.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理        
#endregion
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理
//关键的点,在HttpResponse 输入内容的时候,一定会调用此方法输入数据,所以要在此方法内截获数据
.net中自定义过滤器对Response内容进行处理

public
override
void Write(byte[] buffer, int offset, int count)
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            
string strBuffer = System.Text.UTF8Encoding.UTF8.GetString(buffer, offset, count);
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理
//采用正则,检查输入的是否有页面结束符</html>
.net中自定义过滤器对Response内容进行处理
            Regex eof =
new Regex("</html>", RegexOptions.IgnoreCase);
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理            
if (!eof.IsMatch(strBuffer))
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理            
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理              
//页面没有输出完毕,继续追加内容
.net中自定义过滤器对Response内容进行处理
                responseHtml.Append(strBuffer);
.net中自定义过滤器对Response内容进行处理            }

.net中自定义过滤器对Response内容进行处理            
else
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理            
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理              
//页面输出已经完毕,截获内容
.net中自定义过滤器对Response内容进行处理
                responseHtml.Append(strBuffer);
.net中自定义过滤器对Response内容进行处理                
string finalHtml = responseHtml.ToString();
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理            
//激发数据已经获取事件
.net中自定义过滤器对Response内容进行处理
            OnRawDataRecordedEvent(thisnew RawDataEventArgs(finalHtml));
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理                
//继续传递要发出的内容写入流
.net中自定义过滤器对Response内容进行处理

byte[] data = System.Text.UTF8Encoding.UTF8.GetBytes(finalHtml);
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理                responseStream.Write(data, 
0, data.Length);
.net中自定义过滤器对Response内容进行处理            }

.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理    }

至此,过滤器定义完毕了,接下来还需要把这个过滤器装配到HttpResponse 对象中。
为了能够截获整站的aspx 页面输出的内容,我们可以定义一个HttpModule 来完成。
代码如下:

.net中自定义过滤器对Response内容进行处理using System;
.net中自定义过滤器对Response内容进行处理
using System.Web;
.net中自定义过滤器对Response内容进行处理
using System.Collections.Generic;
.net中自定义过滤器对Response内容进行处理
using System.Text;
.net中自定义过滤器对Response内容进行处理
using System.IO;
.net中自定义过滤器对Response内容进行处理
using System.Diagnostics;
.net中自定义过滤器对Response内容进行处理

.net中自定义过滤器对Response内容进行处理    
public
class HttpRawDataModule : IHttpModule
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理    
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
IHttpModule 成员#region IHttpModule 成员
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
public
void Dispose()
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
public
void Init(HttpApplication context)
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            
//绑定事件,在对此请求处理过程全部结束后进行过滤操作
.net中自定义过滤器对Response内容进行处理
            context.ReleaseRequestState +=
new EventHandler(context_ReleaseRequestState);
.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理        
#endregion
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
/**////
<summary>
.net中自定义过滤器对Response内容进行处理        
/// 对此HTTP请求处理的过程全部结束
.net中自定义过滤器对Response内容进行处理        
///
</summary>
.net中自定义过滤器对Response内容进行处理        
///
<param name="sender"></param>
.net中自定义过滤器对Response内容进行处理        
///
<param name="e"></param>

.net中自定义过滤器对Response内容进行处理
void context_ReleaseRequestState(object sender, EventArgs e)
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            HttpApplication application 
= (HttpApplication)sender;
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理            
//这里需要针对ASPX页面进行拦截,测试发现如果不这么做,Wap 访问站点图片容易显示为X,奇怪
.net中自定义过滤器对Response内容进行处理

string[] temp = application.Request.CurrentExecutionFilePath.Split(.);
.net中自定义过滤器对Response内容进行处理            
if (temp.Length >
0
&& temp[temp.Length -
1].ToLower() ==
"aspx")
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理            
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理                
//装配过滤器
.net中自定义过滤器对Response内容进行处理
                application.Response.Filter =
new RawFilter(application.Response.Filter);
.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理                
//绑定过滤器事件
.net中自定义过滤器对Response内容进行处理
                RawFilter filter = (RawFilter)application.Response.Filter;
.net中自定义过滤器对Response内容进行处理                filter.OnRawDataRecordedEvent 
+=
new EventHandler<RawDataEventArgs>(filter_OnRawDataRecordedEvent);
.net中自定义过滤器对Response内容进行处理            }

.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
/**////
<summary>
.net中自定义过滤器对Response内容进行处理        
/// 当原始数据采集到以后,入库 
.net中自定义过滤器对Response内容进行处理        
///
</summary>
.net中自定义过滤器对Response内容进行处理        
///
<param name="sender"></param>
.net中自定义过滤器对Response内容进行处理        
///
<param name="e"></param>

.net中自定义过滤器对Response内容进行处理
void filter_OnRawDataRecordedEvent(object sender, RawDataEventArgs e)
.net中自定义过滤器对Response内容进行处理.net中自定义过滤器对Response内容进行处理        
.net中自定义过滤器对Response内容进行处理{
.net中自定义过滤器对Response内容进行处理            
string allcode = e.SourceCode;
.net中自定义过滤器对Response内容进行处理            WapSite.SiteDataClass wapdata 
=
new WapSite.SiteDataClass();
.net中自定义过滤器对Response内容进行处理            wapdata.WriteRawDataLog(allcode);
.net中自定义过滤器对Response内容进行处理        }

.net中自定义过滤器对Response内容进行处理    }

.net中自定义过滤器对Response内容进行处理

HttpModule 准备完毕,也装配上了过滤器,接下来还需要在配置文件中配置HttpModules配置节 ,把自定义的HttpModule 加入到HTTP处理管道中。
在Web.config 中增加配置节如下:

.net中自定义过滤器对Response内容进行处理
<system.web>
.net中自定义过滤器对Response内容进行处理    
<httpModules>
.net中自定义过滤器对Response内容进行处理      
<add name="RawDataModule" type="HttpRawDataModule"/>
.net中自定义过滤器对Response内容进行处理    
</httpModules>
.net中自定义过滤器对Response内容进行处理  
</system.web>


测试成功,能准确的获得服务器向客户端输出的HTML内容。

其中,在过滤器中,可以直接对即将要输出的内容做 对于字符串的任意处理。

而且采用这样的方式来对站点即将输出的内容做修改和采集,可以通过修改配置文件,随时打开和关闭,有很强的优越性和灵活性还有重用性。

记得看到过很多需要产生静态页面的网站,都是通过代码HttpWebRequest 向自己请求并记录返回的代码产生静态页面,不知道我当前介绍的方法是否更好写,比如需要产生静态页面时,不管是谁发出请求,由服务器检查自己是否有静态页面,否则产生静态页面,并转向。给出引子,希望大家还是自己开阔思路比较好。
 

 .net中自定义过滤器对Response内容进行处理

.net中自定义过滤器对Response内容进行处理,布布扣,bubuko.com

.net中自定义过滤器对Response内容进行处理

上一篇:构建ASP.NET MVC4+EF5+EasyUI+Unity2.x注入的后台管理系统(29)-T4模版


下一篇:Javascript 中方法的重写