拦截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());

  }

}

时间: 2024-08-14 09:10:51

拦截asp.net输出流并进行处理的方法的相关文章

拦截asp.net输出流做处理, 拦截HTML文本

对已经生成了HTML的页面做一些输出到客户端之前的处理 方法的原理是:把Response的输出重定向到自定义的容器内,也就是我们的StringBuilder对象里,在HTML所有的向页面输出都变 成了向StringBuilder输出,然后我们对StringBuilder处理完成之后,再把Response的输出重定向到原来的页面上,然后再通 过Response.Write方法把StringBuilder的内容输出到页面上 这里之所以用反射,是因为Response对象的OutPut属性是只读的,通过

拦截asp.net输出流做处理

本文标题是指对已经生成了HTML的页面做一些输出到客户端之前的处理. 方法的原理是:把Response的输出重定向到自定义的容器内,也就是我们的StringBuilder对象里,在HTML所有的向页面输出都变成了向StringBuilder输出,然后我们对StringBuilder处理完成之后,再把Response的输出重定向到原来的页面上,然后再通过Response.Write方法把StringBuilder的内容输出到页面上 这里之所以用反射,是因为Response对象的OutPut属性是只

拦截asp.net mvc输出流做处理, 拦截HTML文本(asp.net MVC版)

以前的一个贴子写过一个webForm的拦截HTML输出流的版本,最近用到mvc时用同样的方式发生一些问题. 如下图 查了好久也不知道啥原因. 好吧, 我最后选择放弃. 想起以前自定义Response.Filter 时,里面Write方法可以获取页面流的信息. 这次我借用HttpModule实现拦截HTML内容输出流,下面看代码 一.HtmlHttpModule.cs    定义一个新类继承HttpModule using System; using System.Collections.Gene

ASP.net MVC 文件下载的几种方法

ASP.net MVC 文件下载的几种方法(欢迎讨论) 在ASP.net MVC 中有几种下载文件的方法前提:要下载的文件必须是在服务器目录中的,至于不在web项目server目录中的文件下载我不知道,但是还挺想了解的.第一种:最简单的超链接方法,<a>标签的href直接指向目标文件地址,这样容易暴露地址造成盗链,这里就不说了第二种:后台下载在后台下载中又可以细分为几种下载方式首先,在前台,我们需要一个<a>标签 <a href="~/Home/download&q

ASP.NET MVC学前篇之扩展方法、链式编程

前言 目的没有别的,就是介绍几点在ASP.NETMVC 用到C#语言特性,还有一些其他琐碎的知识点,强行的划分一个范围的话,只能说都跟MVC有关,有的是外围的知识,有的是包含在框架内的. MVC学前篇字样?有噱头的成分也有真实的成分,所以工欲善其事,必先利其器.器是什么?基础嘛,虽然说MVC框架中涉及到的知识很多很多也不是我一篇两篇能说完的,我能做的就是知道多少就跟大家分享多少,当然了随着时间的推移会完善这个系列. 1扩展方法 扩展方法是C# 3.0特性里的知识,它用在最多的地方是在Linq中,

ASP.NET中XML转JSON的方法

原文:ASP.NET中XML转JSON的方法 许多应用程序都将数据存储为XML的格式,而且会将数据以JSON的格式发送到客户端以做进一步处理.要实现这一点,它们必须将XML格式转换为JSON格式. XML转JSON代码 [csharp] view plaincopy private static string XmlToJSON(XmlDocument xmlDoc) { StringBuilder sbJSON = new StringBuilder(); sbJSON.Append("{ &

Asp.net导出Excel乱码的解决方法

通过跟踪Asp.net服务器代码,没有乱码,然而导出Excel到浏览器后,打开时出现乱码. 解决方法是添加编码格式的前缀字节码:Response.BinaryWrite(System.Text.Encoding.Unicode.GetPreamble()); ? 1 2 3 4 5 6 7 8 9 10 11 12 13 Response.Clear(); Response.AddHeader("content-disposition","attachment;filenam

ASP.NET(C#)常用数据加密和解密方法汇总

一.            数据加密的概念 1.  基本概念 2.  基本功能 3.  加密形式 二.            数据加密的项目应用和学习 1.  媒体加密:DRM 2.  文件加密:文本加密.pdf.word 3.  数据加密:ASP.NET(C#)中的数据加密 4.  硬件加密:加密狗 三.            数据加密的发展趋势 四.            网络数据加密算法分类 1.  根本不考虑解密问题:MD5. 2.  私用密钥加密:DES.AES 3.  公用密钥加密:

asp.net中的窗口弹出实现,包括分支窗口 . ASP.NET返回上一页面实现方法总结 .

返回上一页的这个东东在我们做项目的时候一般是用于填写完表单后确认的时候,有对原来输入的数据进行修改或者更新时用的,或者是因为网站为了方便浏览者而有心添加的一个东东,一般这种功能的实现在ASP.NET中都是用一个Button控件来实现的,实现的方法有很多,今天恰好在做项目时碰到要用这个东东,我就把能实现" 返回上一页","返回前一页"的几种方法总结了一下,供大家学习之用,请多多指教: 其实要实现这个功能主要还是要用到javascript脚本语言! 方法一: 在asp.