拦截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程序设计有一定的借鉴价值。

(0)

相关推荐

  • ASP.net(c#)用类的思想实现插入数据到ACCESS例子

    昨天写了一半,一直没弄清楚当ACCESS数据库的连接代码写成类的时候路径该怎么写,搞了半天,还是用绝对路径解决了,似乎Server.MapPath没法在cs文件中使用. 要实现的功能如下: 尽量用类的思想来完成数据的插入,因为这个例子简单,所以我也就不多说什么.大家自己看代码,不懂的可以到论坛交流. 1.首先是ACCESS数据库的设计,数据库名:myData,表名:student 字段名称                    数据类型 sid                          

  • Asp.Net使用Bulk实现批量插入数据

    本文实例讲述了Asp.Net使用Bulk实现批量插入数据的方法,分享给大家供大家参考之用.具体方法如下: 主要功能代码如下: using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Diagnostics; using System.Data; using System.Data.SqlClient; using System.Configuration;

  • 快速插入大量数据的asp.net代码(Sqlserver)

    复制代码 代码如下: using System.Data; using System.Diagnostics; using System.Data.SqlClient; string connectionString = "Data Source=HG-J3EJJ9LSW5PY;Initial Catalog=Test;User ID=sa;password=hg"; DataTable dataTable = sql_.select_datagrid(" select a

  • asp.net 读取文本文件并插入数据库的实现代码

    由此,需要操作以下几个步骤 1,上传txt文件至公司系统 2,读取需要的内容 3,将内容插入到数据库中(需要判断重复) 4,与现有订单数据进行对比 本程序只研究读取需要的内容和插入数据库 复制代码 代码如下: using System; using System.Data; using System.Collections.Generic; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using

  • 推荐8项提高 ASP.NET Web API 性能的技术

    在本文中,我将介绍8项提高 ASP.NET Web API 性能的技术. 1) 使用最快的 JSON 序列化工具 JSON 的序列化对整个 ASP.NET Web API 的性能有着关键性的影响.在我的一个项目里,我从JSON.NET 序列化工具转到了ServiceStack.Text有一年半了. 我测量过,Web API 的性能提升了20%左右.我强烈建议你去尝试一下这个序列化工具.这里有一些最近的流行序列化工具性能的比较数据. 来源:theburningmonk 更新: 似乎It seams

  • asp.net页面SqlCacheDependency缓存实例

    缓存技术是asp.net程序设计中非常实用的技术,也是大型web程序设计中比较常见的技术.本文就以实例形式对此加以说明.具体如下: asp.net页面的SqlCacheDependency Sql缓存: Cahce/SqlCachePage.aspx页面代码如下: <%@ Page Language="C#" MasterPageFile="~/Site.master" AutoEventWireup="true" CodeFile=&qu

  • asp.net 使用SqlBulkCopy极速插入数据到 SQL Server

    按这个来算,我们那个发水票的时间就会由 10分钟-->20秒,这可太神奇了. 于是乎,下demo,测试,改成自己一般使用的方法测试,NND,还真可以说是极速. 在此贴上我的Demo:SqlBulkCopy.rar 复制代码 代码如下: using System; using System.Diagnostics; using System.Data; using System.Data.SqlClient; using Microsoft.ApplicationBlocks.Data; name

  • Asp.Net使用Npoi导入导出Excel的方法

    asp.net针对Excel文件的导入与导出是非常常见的功能之一.本文实例讲述了Asp.Net使用Npoi导入导出Excel的方法.分享给大家供大家参考之用.具体方法如下: 在使用Npoi导出Excel的时候,服务器可以不装任何office组件,一般在导出时用到Npoi导出Excel文件,所导Excel也符合规范,打开时也不会有任何文件损坏之类的提示.但是在做导入时还是使用OleDb的方式,这种方式的导入在服务器端似乎还是需要装office组件的. 一.Npoi导出/下载Excel 具体功能代码

  • asp.net利用后台实现直接生成html分页的方法

    本文实例讲述了asp.net利用后台实现直接生成html分页的方法,是一个比较实用的功能.分享给大家供大家参考之用.具体方法如下: 1.建立存储过程: ALTER procedure [dbo].[p_news_query] @Page int as begin select top 5 new_id,new_title,new_url,new_content_text,create_time,user_name from (select *,ROW_NUMBER() over(order by

  • 拦截asp.net输出流并进行处理的方法

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

  • ASP.Net下载大文件的实现方法

    本文实例讲述了ASP.Net下载大文件的实现方法.分享给大家供大家参考.具体分析如下: 当我们的网站需要支持下载大文件时,如果不做控制可能会导致用户在访问下载页面时发生无响应,使得浏览器崩溃.可以参考如下代码来避免这个问题. 关于此代码的几点说明: 1. 将数据分成较小的部分,然后将其移动到输出流以供下载,从而获取这些数据. 2. 根据下载的文件类型来指定 Response.ContentType .(参考OSChina的这个网址可以找到大部分文件类型的对照表:http://tool.oschi

  • asp.net实现C#绘制太极图的方法

    本文实例讲述了asp.net实现C#绘制太极图的方法.分享给大家供大家参考.具体如下: 成品图如下所示: html页面: 注意设置: 复制代码 代码如下: ContentType="Image/Jpeg" 复制代码 代码如下: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="TaiJiTu.aspx.cs" Inherits="TaiJiTu&qu

  • ASP.NET抓取网页内容的实现方法

    本文实例讲述了ASP.NET抓取网页内容的实现方法.分享给大家供大家参考.具体实现方法如下: 一.ASP.NET 使用HttpWebRequest抓取网页内容 复制代码 代码如下: /// <summary>方法一:比较推荐  /// 用HttpWebRequest取得网页源码  /// 对于带BOM的网页很有效,不管是什么编码都能正确识别  /// </summary>  /// <param name="url">网页地址" </

  • asp 延时 页面延迟的三种方法

    ASP页面延迟的两个简单方法 asp延时第一种 复制代码 代码如下: <% Response.Buffer = True %> <% ' Setup the variables necessary to accomplish the task Dim TimerStart, TimerEnd, TimerNow, TimerWait ' How many seconds do you want them to wait... TimerWait = 5 ' Setup and start

  • Asp.net MVC定义短网址的方法

    在MVC的逻辑代码里,Controller和Action是必须的,但是在网址里,并不需要完全体现Controller和Action.比如我们经常希望看到http://localhost/About而不是http://localhost/Home/About. 默认的路由规则 新建MVC应用程序后,Global.asax里默认注册的路由规则是: public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRout

  • win2003服务器asp.net权限设置问题及解决方法

    服务器asp.net权限设置问题及解决方法 本人服务器使用环境:WIN 2003 ASP.NET相对于ASP,设置权限方面有点不同,有一点儿设置错了都运行不到.在网上搜索到的都是很垃圾的答案,没有一个用得到的,下面是我自己设置并从中遇到的问题摸索后得到的经验,给大家分享. ASP.NET需要用到USERS组的权限,因为我也遇过很多次自己设置了权限之后发现网站运行不了,很郁闷.下面根据出现的问题,一点点解决,让你的ASP.NET运行起来.. 问题一: 未找到路径"C:\"的一部分. 说明

  • ASP.NET防范SQL注入式攻击的方法

    一.什么是SQL注入式攻击?  SQL注入式攻击就是攻击者把SQL命令插入到Web表单的输入域或页面请求的查询字符串,欺骗服务器执行恶意的SQL命令.在某些表单中,用户输入的内容直接用来构造(或者影响)动态SQL命令,或作为存储过程的输入参数,这类表单特别容易受到SQL注入式攻击.常见的SQL注入式攻击过程类如: ⑴ 某个ASP.NET Web应用有一个登录页面,这个登录页面控制着用户是否有权访问应用,它要求用户输入一个名称和密码. ⑵ 登录页面中输入的内容将直接用来构造动态的SQL命令,或者直

  • ASP.NET网站实时显示时间的方法

    本文实例讲述了ASP.NET网站实时显示时间的方法.分享给大家供大家参考.具体方法如下: 在ASP.NET环境中开发设计网站或网络应用程序时,往往需要实时显示当前日期和时间.这时,通常使用AJAX控件来实现. 需要注意的是,在.NET Framework 2.0版本中,工具箱中是没有AJAX Extensions控件的.而.NET Framework 3.5版本中集成了AJAX. ASP.NET AJAX包括三部分: ①一个扩展客户端JavaScript功能的客户端库或框架: ②一个允许ASP.

  • asp.net清空Cookie的两种方法

    asp.net清空Cookie的两种方法 第一种 Cookie.Expires=[DateTime]; Response.Cookies("UserName").Expires = 0; 第二种 Response.Cookies["admin"].Expires = DateTime.Now.AddDays(-1);

随机推荐