拦截asp.net输出流并进行处理的方法
本文实例主要实现对已经生成了HTML的页面做一些输出到客户端之前的处理。
方法的实现原理是:把Response的输出重定向到自定义的容器内,也就是我们的StringBuilder对象里,在HTML所有的向页面输出都变成了向StringBuilder输出,然后我们对StringBuilder处理完成之后,再把Response的输出重定向到原来的页面上,然后再通过Response.Write方法把StringBuilder的内容输出到页面上。
这里之所以用反射,是因为Response对象的OutPut属性是只读的,通过反编译该类的程序集发现,OutPut实际上是内部私有成员_writer来实现输出的。因此通过反射来改写该成员的值以实现输出流的重定向。
具体功能代码如下:
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Web; usingSystem.Web.UI; usingSystem.Web.UI.WebControls; usingSystem.Text; usingSystem.IO; usingSystem.Reflection; publicpartialclass_Default:System.Web.UI.Page { StringBuildercontent=newStringBuilder(); TextWritertw_old,tw_new; FieldInfotw_field; protectedvoidPage_Load(objectsender,EventArgse) { varcontext=HttpContext.Current; tw_old=context.Response.Output;//Response原来的OutPut tw_new=newStringWriter(content);//一个StringWriter,用来获取页面内容 vartype_rp=context.Response.GetType(); //通过反射获取对象的私有字段 tw_field=type_rp.GetField("_writer",System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.NonPublic|System.Reflection.BindingFlags.Instance); tw_field.SetValue(context.Response,tw_new); } protectedoverridevoidRender(HtmlTextWriterwriter) { base.Render(writer); //替换回Response的OutPut tw_field.SetValue(HttpContext.Current.Response,tw_old); //做自己的处理 content.AppendLine("<!--江湖小子-->"); HttpContext.Current.Response.Write(content.ToString()); } }
方法二,用HttpModul来实现:
usingSystem; usingSystem.Collections.Generic; usingSystem.Linq; usingSystem.Web; usingSystem.Web.UI; usingSystem.IO; usingSystem.Text; usingSystem.Reflection; ///<summary> ///HttpModule的摘要说明 ///</summary> publicclassHttpModule:IHttpModule { privateHttpApplication_contextApplication; privateTextWritertw_new,tw_old; privateStringBuilder_content; privateFieldInfotw_field; publicvoidInit(HttpApplicationcontext) { _contextApplication=context; _contextApplication.PreRequestHandlerExecute+=newEventHandler(_contextApplication_PreRequestHandlerExecute); } publicvoidDispose() { _contextApplication=null; _contextApplication.Dispose(); } publicvoid_contextApplication_PreRequestHandlerExecute(objectsender,EventArgse) { HttpContextcontext=_contextApplication.Context; var_page=context.HandlerasSystem.Web.UI.Page; _page.Unload+=newEventHandler(_page_Unload); _content=newStringBuilder(); tw_old=context.Response.Output;//Response原来的OutPut tw_new=newStringWriter(_content);//一个StringWriter,用来获取页面内容 vartype_rp=context.Response.GetType(); tw_field=type_rp.GetField("_writer",System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.NonPublic|System.Reflection.BindingFlags.Instance); tw_field.SetValue(context.Response,tw_new); } void_page_Unload(objectsender,EventArgse) { //替换回Response的OutPut tw_field.SetValue(HttpContext.Current.Response,tw_old); //做自己的处理 _content.AppendLine("<!--江湖小子-->"); HttpContext.Current.Response.Write(_content.ToString()); } }
方法三:
publicclassHttpModule:IHttpModule { privateHttpApplication_contextApplication; privateTextWritertw_new,tw_old; privateStringBuilder_content; privateFieldInfotw_field; publicvoidInit(HttpApplicationapplication) { _contextApplication=application; _contextApplication.BeginRequest+=newEventHandler(_contextApplication_BeginRequest); _contextApplication.EndRequest+=newEventHandler(_contextApplication_EndRequest); } void_contextApplication_BeginRequest(objectsender,EventArgse) { _content=newStringBuilder(); tw_old=_contextApplication.Response.Output; tw_new=newStringWriter(_content); vartype_rp=_contextApplication.Response.GetType(); tw_field=type_rp.GetField("_writer",System.Reflection.BindingFlags.Public|System.Reflection.BindingFlags.NonPublic|System.Reflection.BindingFlags.Instance); tw_field.SetValue(_contextApplication.Response,tw_new); } void_contextApplication_EndRequest(objectsender,EventArgse) { tw_field.SetValue(_contextApplication.Response,tw_old); //做自己的处理 _content.AppendLine("<!--jhxz-->"); _contextApplication.Response.Write(_content.ToString()); } publicvoidDispose() { _contextApplication=null; _contextApplication.Dispose(); } }
相信本文所述对大家的asp.net程序设计有一定的借鉴价值。