本文标题是指对已经生成了HTML的页面做一些输出到客户端之前的处理。

方法的原理是:把Response的输出重定向到自定义的容器内,也就是我们的StringBuilder对象里,在HTML所有的向页面输出都变成了向StringBuilder输出,然后我们对StringBuilder处理完成之后,再把Response的输出重定向到原来的页面上,然后再通过Response.Write方法把StringBuilder的内容输出到页面上

这里之所以用反射,是因为Response对象的OutPut属性是只读的,通过反编译该类的程序集发现,OutPut实际上是内部私有成员 _writer来实现输出的。因此通过反射来改写该成员的值以实现输出流的重定向。

  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Web;
  5. using System.Web.UI;
  6. using System.Web.UI.WebControls;
  7. using System.Text;
  8. using System.IO;
  9. using System.Reflection;
  10. public partial class _Default : System.Web.UI.Page
  11. {
  12. StringBuilder content = new StringBuilder();
  13. TextWriter tw_old, tw_new;
  14. FieldInfo tw_field;
  15. protected void Page_Load(object sender, EventArgs e)
  16. {
  17. var context = HttpContext.Current;
  18. tw_old = context.Response.Output;//Response原来的OutPut
  19. tw_new = new StringWriter(content);//一个StringWriter,用来获取页面内容
  20. var type_rp = context.Response.GetType();
  21. //通过反射获取对象的私有字段
  22. tw_field = type_rp.GetField("_writer", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
  23. tw_field.SetValue(context.Response, tw_new);
  24. }
  25. protected override void Render(HtmlTextWriter writer)
  26. {
  27. base.Render(writer);
  28. //替换回Response的OutPut
  29. tw_field.SetValue(HttpContext.Current.Response, tw_old);
  30. //做自己的处理
  31. content.AppendLine("<!--江湖小子-->");
  32. HttpContext.Current.Response.Write(content.ToString());
  33. }
  34. }
  35. 方法二,用HttpModul来实现:
  36. using System;
  37. using System.Collections.Generic;
  38. using System.Linq;
  39. using System.Web;
  40. using System.Web.UI;
  41. using System.IO;
  42. using System.Text;
  43. using System.Reflection;
  44. /// <summary>
  45. ///HttpModule 的摘要说明
  46. /// </summary>
  47. public class HttpModule : IHttpModule
  48. {
  49. private HttpApplication _contextApplication;
  50. private TextWriter tw_new, tw_old;
  51. private StringBuilder _content;
  52. private FieldInfo tw_field;
  53. public void Init(HttpApplication context)
  54. {
  55. _contextApplication = context;
  56. _contextApplication.PreRequestHandlerExecute += new EventHandler(_contextApplication_PreRequestHandlerExecute);
  57. }
  58. public void Dispose()
  59. {
  60. _contextApplication = null;
  61. _contextApplication.Dispose();
  62. }
  63. public void _contextApplication_PreRequestHandlerExecute(object sender, EventArgs e)
  64. {
  65. HttpContext context = _contextApplication.Context;
  66. var _page = context.Handler as System.Web.UI.Page;
  67. _page.Unload += new EventHandler(_page_Unload);
  68. _content = new StringBuilder();
  69. tw_old = context.Response.Output;//Response原来的OutPut
  70. tw_new = new StringWriter(_content);//一个StringWriter,用来获取页面内容
  71. var type_rp = context.Response.GetType();
  72. tw_field = type_rp.GetField("_writer", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
  73. tw_field.SetValue(context.Response, tw_new);
  74. }
  75. void _page_Unload(object sender, EventArgs e)
  76. {
  77. //替换回Response的OutPut
  78. tw_field.SetValue(HttpContext.Current.Response, tw_old);
  79. //做自己的处理
  80. _content.AppendLine("<!--江湖小子-->");
  81. HttpContext.Current.Response.Write(_content.ToString());
  82. }
  83. }
  84. 方法三:
  85. public class HttpModule : IHttpModule
  86. {
  87. private HttpApplication _contextApplication;
  88. private TextWriter tw_new, tw_old;
  89. private StringBuilder _content;
  90. private FieldInfo tw_field;
  91. public void Init(HttpApplication application)
  92. {
  93. _contextApplication = application;
  94. _contextApplication.BeginRequest += new EventHandler(_contextApplication_BeginRequest);
  95. _contextApplication.EndRequest +=new EventHandler(_contextApplication_EndRequest);
  96. }
  97. void _contextApplication_BeginRequest(object sender, EventArgs e)
  98. {
  99. _content = new StringBuilder();
  100. tw_old = _contextApplication.Response.Output;
  101. tw_new = new StringWriter(_content);
  102. var type_rp = _contextApplication.Response.GetType();
  103. tw_field = type_rp.GetField("_writer", System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
  104. tw_field.SetValue(_contextApplication.Response, tw_new);
  105. }
  106. void _contextApplication_EndRequest(object sender, EventArgs e)
  107. {
  108. tw_field.SetValue(_contextApplication.Response, tw_old);
  109. //做自己的处理
  110. _content.AppendLine("<!--jhxz-->");
  111. _contextApplication.Response.Write(_content.ToString());
  112. }
  113. public void Dispose()
  114. {
  115. _contextApplication = null;
  116. _contextApplication.Dispose();
  117. }
  118. }

最后还是推荐一篇好文:码农欧洲出差的一点小插曲

最新文章

  1. Chrome 监听 console 打开
  2. 多层嵌套对象无法使用gson反序列化的问题The JsonDeserializer com.google.gson.DefaultTypeAdapters$CollectionTypeAdapter@3bf13cde failed to de
  3. Java Hour8
  4. Impala入门笔记
  5. Javascript 备忘
  6. Android--------- SD卡存储文件报错解决
  7. poj 3111 K Best (二分搜索之最大化平均值之01分数规划)
  8. vb和vb.net事件机制
  9. Python中的枚举
  10. ionic2使用cordova打包的环境搭建
  11. 前端学习roadmap
  12. 洛谷P3354 河流
  13. Confluence 6 CSS 编辑快速入门
  14. LBS
  15. 利用数据库触发器让字段与自增长Id相关联
  16. JavaScript比较两个对象的值是否相等
  17. com.alibaba.com.caucho.hessian.io.SerializerFactory getDeserializer
  18. 【多线程系列】AQS CAS简单介绍
  19. android2.2应用开发之IccCard(sim卡或USIM卡)(转至 http://www.2cto.com/kf/201306/223784.html)
  20. Linux 通过程序名获取进程ID并Kill

热门文章

  1. lintcode-512-解码方法
  2. nginx 二进制安装
  3. 【第八周】beta阶段事后诸葛亮会议
  4. Linux的计划任务
  5. MySql中的varchar类型
  6. shit Rap &amp; mock api
  7. postman md5加密 然后传给下一个接口作为参数调用
  8. HDU4646_Laser Beam
  9. 【bzoj5028】小Z的加油店 扩展裴蜀定理+差分+线段树
  10. P1065 作业调度方案