拦截asp.net输出流做处理
本文标题是指对已经生成了HTML的页面做一些输出到客户端之前的处理。
方法的原理是:把Response的输出重定向到自定义的容器内,也就是我们的StringBuilder对象里,在HTML所有的向页面输出都变成了向StringBuilder输出,然后我们对StringBuilder处理完成之后,再把Response的输出重定向到原来的页面上,然后再通过Response.Write方法把StringBuilder的内容输出到页面上
这里之所以用反射,是因为Response对象的OutPut属性是只读的,通过反编译该类的程序集发现,OutPut实际上是内部私有成员 _writer来实现输出的。因此通过反射来改写该成员的值以实现输出流的重定向。
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.UI;
- using System.Web.UI.WebControls;
- using System.Text;
- using System.IO;
- using System.Reflection;
- public partial class _Default : System.Web.UI.Page
- {
- StringBuilder content = new StringBuilder();
- TextWriter tw_old, tw_new;
- FieldInfo tw_field;
- protected void Page_Load(object sender, EventArgs e)
- {
- var context = HttpContext.Current;
- tw_old = context.Response.Output;//Response原来的OutPut
- tw_new = new StringWriter(content);//一个StringWriter,用来获取页面内容
- var type_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);
- }
- protected override void Render(HtmlTextWriter writer)
- {
- base.Render(writer);
- //替换回Response的OutPut
- tw_field.SetValue(HttpContext.Current.Response, tw_old);
- //做自己的处理
- content.AppendLine("<!--江湖小子-->");
- HttpContext.Current.Response.Write(content.ToString());
- }
- }
- 方法二,用HttpModul来实现:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.UI;
- using System.IO;
- using System.Text;
- using System.Reflection;
- /// <summary>
- ///HttpModule 的摘要说明
- /// </summary>
- public class HttpModule : IHttpModule
- {
- private HttpApplication _contextApplication;
- private TextWriter tw_new, tw_old;
- private StringBuilder _content;
- private FieldInfo tw_field;
- public void Init(HttpApplication context)
- {
- _contextApplication = context;
- _contextApplication.PreRequestHandlerExecute += new EventHandler(_contextApplication_PreRequestHandlerExecute);
- }
- public void Dispose()
- {
- _contextApplication = null;
- _contextApplication.Dispose();
- }
- public void _contextApplication_PreRequestHandlerExecute(object sender, EventArgs e)
- {
- HttpContext context = _contextApplication.Context;
- var _page = context.Handler as System.Web.UI.Page;
- _page.Unload += new EventHandler(_page_Unload);
- _content = new StringBuilder();
- tw_old = context.Response.Output;//Response原来的OutPut
- tw_new = new StringWriter(_content);//一个StringWriter,用来获取页面内容
- var type_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(object sender, EventArgs e)
- {
- //替换回Response的OutPut
- tw_field.SetValue(HttpContext.Current.Response, tw_old);
- //做自己的处理
- _content.AppendLine("<!--江湖小子-->");
- HttpContext.Current.Response.Write(_content.ToString());
- }
- }
- 方法三:
- public class HttpModule : IHttpModule
- {
- private HttpApplication _contextApplication;
- private TextWriter tw_new, tw_old;
- private StringBuilder _content;
- private FieldInfo tw_field;
- public void Init(HttpApplication application)
- {
- _contextApplication = application;
- _contextApplication.BeginRequest += new EventHandler(_contextApplication_BeginRequest);
- _contextApplication.EndRequest +=new EventHandler(_contextApplication_EndRequest);
- }
- void _contextApplication_BeginRequest(object sender, EventArgs e)
- {
- _content = new StringBuilder();
- tw_old = _contextApplication.Response.Output;
- tw_new = new StringWriter(_content);
- var type_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(object sender, EventArgs e)
- {
- tw_field.SetValue(_contextApplication.Response, tw_old);
- //做自己的处理
- _content.AppendLine("<!--jhxz-->");
- _contextApplication.Response.Write(_content.ToString());
- }
- public void Dispose()
- {
- _contextApplication = null;
- _contextApplication.Dispose();
- }
- }
最后还是推荐一篇好文:码农欧洲出差的一点小插曲
拦截asp.net输出流做处理的更多相关文章
- 拦截asp.net输出流做处理, 拦截HTML文本(asp.net webForm版)
对已经生成了HTML的页面做一些输出到客户端之前的处理 方法的原理是:把Response的输出重定向到自定义的容器内,也就是我们的StringBuilder对象里,在HTML所有的向页面输出都变 成了 ...
- 拦截asp.net输出流并进行处理的方法
本文实例主要实现对已经生成了HTML的页面做一些输出到客户端之前的处理. 方法的实现原理是:把Response的输出重定向到自定义的容器内,也就是我们的StringBuilder对象里,在HTML所有 ...
- 拦截asp.net mvc输出流做处理, 拦截HTML文本(asp.net MVC版)
以前的一个贴子写过一个webForm的拦截HTML输出流的版本,最近用到mvc时用同样的方式发生一些问题. 如下图 查了好久也不知道啥原因. 好吧, 我最后选择放弃. 想起以前自定义Response. ...
- ASP.NET CORE做的网站运行在docker实践
用VS2017 建立了 DotNet Core 2.2 的网站后,如何转移到 Docker 下运行? 下面分两种方式来实践: 1.直接手动命今行,将本机目录映射进Docker,运行网站.2.制作 Im ...
- ASP.NET MVC 做的网站项目
感谢博客园团队日夜为广大需要获取知识人们所做的奉献 博客园团队您们辛苦了 ASP.NET MVC 实现有论坛功能的网站(有iis发布网站 这是之前写的... www.lazyfitness.cn 经过 ...
- 牛腩学ASP.NET CORE做博客(视频)
牛腩学习ASP.NET CORE做的项目,边学边做. 目录: 01-dotnetcore网站部署到centos7系统上(时长 2:03:16) 02-前期准备及项目搭建 (时长:0:23:35) 03 ...
- win10 uwp 使用 asp dotnet core 做图床服务器客户端
原文 win10 uwp 使用 asp dotnet core 做图床服务器客户端 本文告诉大家如何在 UWP 做客户端和 asp dotnet core 做服务器端来做一个图床工具 服务器端 从 ...
- win10 uwp 手把手教你使用 asp dotnet core 做 cs 程序
本文是一个非常简单的博客,让大家知道如何使用 asp dot net core 做后台,使用 UWP 或 WPF 等做前台. 本文因为没有什么业务,也不想做管理系统,所以看到起来是很简单. Visua ...
- ASP.NET输出流至少要有256个字节的数据后Response.Flush方法才会生效
很多时候我们写的asp.net程序会因为做很多操作,所以会花上一分钟甚至几分钟时间.为了使软件使用者能够耐心的等待程序的执行,我们经常会希望有一个进度条来表示程序执行的状态.或者最起码要显示一个类似: ...
随机推荐
- 期中HTML代码及技术博客
<!DOCTYPE html> <html lang="en"> <head> <meta charset="U ...
- C++对象内存布局测试总结
C++对象内存布局测试总结 http://hi.baidu.com/����/blog/item/826d38ff13c32e3a5d6008e8.html 上文是半年前对虚函数.虚拟继承的理解.可能 ...
- 利用书签功能对TDBGrid控件中多个记录的处理
DELPHI 的TDBGrid 控 件 主 要 用 来 处 理 数 据 表, 它 的 属 性 中 有 一 个dgMultiSelect, 若 此 属 性 设 定 为TRUE, 则 可 以 选 中 多 ...
- 【转】小心stringstream.str()字符串用法的陷阱
--------------------- 作者:心中那自由的世界 来源:CSDN 原文:https://blog.csdn.net/119365374/article/details/7744678 ...
- 已知UIScrollView放大后的Frame和放大之前的Frame计算放大的瞄点坐标
有时候在缩放后,需要知道该次缩放是在哪个坐标开始缩放的.如上篇已知缩放的点,然后在该点对其缩放.本篇其实是逆运算 (x,y)就是当初在该点进行缩放 化简之后很简单,代码如下: func getZoom ...
- 洛谷P1602 Sramoc问题 题解报告【同余+bfs】
题目描述 话说员工们整理好了筷子之后,就准备将快餐送出了,但是一看订单,都傻眼了:订单上没有留电话号码,只写了一个sramoc(k,m)函数,这什么东西?什么意思?于是餐厅找来了资深顾问团的成员,YQ ...
- 洛谷 P4027 [NOI2007]货币兑换 解题报告
P4027 [NOI2007]货币兑换 题目描述 小 \(Y\) 最近在一家金券交易所工作.该金券交易所只发行交易两种金券:\(A\) 纪念券(以下简称 \(A\) 券)和 \(B\) 纪念券(以下简 ...
- 洛谷 P1233 木棍加工 解题报告
P1233 木棍加工 题目描述 一堆木头棍子共有n根,每根棍子的长度和宽度都是已知的.棍子可以被一台机器一个接一个地加工.机器处理一根棍子之前需要准备时间.准备时间是这样定义的: 第一根棍子的准备时间 ...
- 20165218 2017-2018-2 《Java程序设计》课程总结
20165218 2017-2018-2 <Java程序设计>课程总结 一.每周作业链接汇总 20165218 我期望的师生关系 20165218 学习基础和C语言基础调查 2016521 ...
- 专题训练之区间DP
例题:以下例题部分的内容来自https://blog.csdn.net/my_sunshine26/article/details/77141398 一.石子合并问题 1.(NYOJ737)http: ...