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

对已经生成了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();
        }
    }  
时间: 2024-11-05 20:43:05

拦截asp.net输出流做处理, 拦截HTML文本的相关文章

拦截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输出流并进行处理的方法

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

springboot+springmvc拦截器做登录拦截

springboot+springmvc拦截器做登录拦截 LoginInterceptor 实现 HandlerInterceptor 接口,自定义拦截器处理方法 LoginConfiguration 实现 WebMvcConfigurer 接口,注册拦截器 ResourceBundle 加载 properties文件数据,配置不进行拦截的路径 LoginInterceptor package com.ytkj.smart_sand.system.interceptor; import com.

Struts2拦截器之ExceptionMappingInterceptor(异常映射拦截器)

一.异常拦截器是什么? 异常拦截器的作用是提供一个机会,可以设置在action执行过程中发生异常的时候映射到一个结果字符串而不是直接中断. 将异常整合到业务逻辑中,比如在分层系统的调用中可以从底层抛出一个异常,高层捕捉到这个异常就知道发生了什么事情啦. 二.如何使用? 1.两种异常映射类型: 1.1.global global的异常映射对整个package下的action都有效: <struts> <package name="default" namespace=&

Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,拦截器Ajax请求

Java过滤器处理Ajax请求,Java拦截器处理Ajax请求,拦截器Ajax请求 java 判断请求是不是ajax请求,Java判断是否为ajax请求 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ?Copyright 蕃薯耀 2017年8月10日 http://www.cnblogs.com/

codevs1044 拦截导弹==洛谷 P1020 导弹拦截

P1020 导弹拦截 题目描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹来袭.由于该系统还在试用阶段,所以只有一套系统,因此有可能不能拦截所有的导弹. 输入导弹依次飞来的高度(雷达给出的高度数据是不大于30000的正整数),计算这套系统最多能拦截多少导弹,如果要拦截所有导弹最少要配备多少套这种导弹拦截系统. 输入输出格式 输入格式: 一行,若干个正

ASP.NET MVC 做的网站项目

感谢博客园团队日夜为广大需要获取知识人们所做的奉献 博客园团队您们辛苦了 ASP.NET MVC 实现有论坛功能的网站(有iis发布网站 这是之前写的... www.lazyfitness.cn 经过一个月的修正 通过ASP.NET MVC 所做的网站www.lazyfitness.cn正式发布了!!! 这个网站不再像之前的哪样页面简陋功能单一了(毕竟之前的是一周做的...) 丰富了很多功能,还有后台管理员哦~ 值得一提的是,这个全部是基于APS.NET MVC框架实现的,我在博客园其实看到用A

ASP.NET CORE做的网站运行在docker上(不用dockerfile文件部署)

原文:ASP.NET CORE做的网站运行在docker上(不用dockerfile文件部署) 按网上的做法用dockerfile文件是可以弄得出来的,http://www.docker.org.cn/article/119.html, 不过我想把网站文件放在外面硬盘目录,再映射进去,这样只要在硬盘目录中修改CSHTML文件后重启一下容器就行了 步骤如下: 1. vs中建立ASP.NET CORE网站,类名为coreweb1 2. 发布到c:\temp\coreweb1目录 3. 先在本地CMD