asp.net 使用页适配器和重写Render对全站输出的页面的HTML内容进行修改,不会错乱

两个比较重点的知识:

1.使用页适配器:http://www.cnblogs.com/sifang2004/archive/2006/05/31/414182.html

如果用新建一个pageBase:Page 来给所有页面继承,程序改动非常大,还有可能改少了。使用页适配器刚好可以达到可插拔的效果,功能又一样。

2.重写Render:http://www.cnblogs.com/mxw09/archive/2010/12/15/1906783.html

链接里的文章说的很清楚了,使用传统的法写会导致输出以后html内容顺序错乱,比如:Substitution控件,它生成的HTML总是跑到HTML最上面

功能:把站点输出的HTML以publicimg开头的字符串前面加上http://loaclhost:17100

页适配器配置文法:1.在WEB项目里新增App_Browsers文件夹,新增一个Default.browser文件,在<browsers>节点里新增

<browser refID="Default">

<controlAdapters>

<adapter controlType="System.Web.UI.Page"

adapterType="TestWeb.MyPageAdapter,TestWeb" />

</controlAdapters>

</browser>

代码如下:

namespace TestWeb{
public class MyPageAdapter : System.Web.UI.Adapters.PageAdapter
    {
        public string GetRenderHtml(HtmlTextWriter writer)
        {
            var Response = this.Page.Response;

            //Response.Output其实就是一个HttpWriter,Response.OutputStream其实就是HttpResponseStream,Object.ReferenceEquals (Response.Output,(Response.OutputStream as HttpResponseStream)._writer)为true

            BindingFlags bind = BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.IgnoreCase | BindingFlags.GetField;
            //因为HttpWriter._charBuffer这个字符数组的长度是1024,
            //所以推测,一旦某一段字符串超过1024就会创建一个IHttpResponseElement,
            //然后加入到HttpWriter._buffers,HttpWriter._buffers的每一个元素都实现了IHttpResponseElement接口,
            //具体类型可能是HttpResponseUnmanagedBufferElement,HttpSubstBlockResponseElement等类型
            ArrayList arr = (ArrayList)Response.Output.GetType().GetField("_buffers", bind).GetValue(Response.Output);

            Assembly systemWeb = Assembly.Load("System.Web, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a");
            Type type = systemWeb.GetType("System.Web.IHttpResponseElement");
            MethodInfo method = type.GetMethod("GetBytes");
            StringBuilder sb = new StringBuilder(5000);
            //遍历每一个buffer,获取buffer里存储的字符数组,然后转换为字符串
            for (int i = 0; i < arr.Count; i++)
            {
                byte[] buffer = (byte[])method.Invoke(arr[i], null);
                //使用当前编码得出已经存储到HttpWriter._buffers中的字符串
                sb.Append(Response.ContentEncoding.GetString(buffer));
            }
            //获取HttpWriter的字符数组缓冲区
            char[] charBuffer = (char[])Response.Output.GetType().GetField("_charBuffer", bind).GetValue(Response.Output);
            int charBufferLength = (int)Response.Output.GetType().GetField("_charBufferLength", bind).GetValue(Response.Output);
            int charBufferFree = (int)Response.Output.GetType().GetField("_charBufferFree", bind).GetValue(Response.Output);
            //charBufferLength - charBufferFree 等于字符数组缓冲区已经使用的字符数量
            for (int i = 0; i < charBufferLength - charBufferFree; i++)
            {
                sb.Append(charBuffer[i]);
            }
            string html = sb.ToString();
            return html;
        }
        protected override void Render(HtmlTextWriter writer)
        {
            base.Render(writer);
            string html = GetRenderHtml(writer);
            html = GetNewImageUrl(html);
            this.Page.Response.ClearContent();
            this.Page.Response.Write(html);
        }
        public string GetNewImageUrl(string html)
        {
            string reg = "\"/publicimg/[^\"\"]*\"|\'/publicimg/[^\'\']*\'";
            reg += "|\\(/publicimg/[^\\(\\)]*\\)";
            return Regex.Replace(html, reg
                , new MatchEvaluator(GetNewImageUrlTag),
                                            RegexOptions.IgnoreCase
                                          | RegexOptions.Multiline
                                          | RegexOptions.IgnorePatternWhitespace
                                          | RegexOptions.Compiled);
        }
        private string GetNewImageUrlTag(Match match)
        {
            string quotesStart = match.Groups[0].Value[0].ToString();
            string quotesEnd = match.Groups[0].Value[match.Groups[0].Value.Length - 1].ToString();
            string imgName = match.Groups[0].Value.ToLower().Replace(quotesStart, "").Replace(quotesEnd, "");
            if (!string.IsNullOrEmpty(imgName) && imgName.StartsWith("/publicimg/"))
            {
                imgName = "http://loaclhost:17100/"+imgName;
            }
            return quotesStart + imgName + quotesEnd;
        }

    }
}
时间: 2024-10-10 00:50:13

asp.net 使用页适配器和重写Render对全站输出的页面的HTML内容进行修改,不会错乱的相关文章

asp.net 使用HttpModule对全站输出的动态页面的HTML内容进行修改,不会错乱

比上一编<asp.net 使用页适配器和重写Render对全站输出的页面的HTML内容进行修改,不会错乱>更容易的方方 http://blog.csdn.net/lrxin/article/details/40861039 配置方法: <httpModules> <add name="FileEditModule" type="Framework.FileEditModule, Framework" /> </httpMod

ASP.NET重写Render 加载CSS样式文件和JS文件(切换CSS换皮肤)

网页换皮肤的方式有很多种,最简单的通常就是切换页面CSS,而CSS通常写在外部CSS文件里.那么切换CSS其实就是更换html里的link href路径.我在网上搜索了下. 一般有两种方式: 1.页面放一个Holder控件.然后用编程方式把当前用户的风格css link写入页面. 2.过反射机制,逐个控件设置css样式. 上面两种方式都挺麻烦的,第一种需要在每个页面上放一个holder控件,类似的做法还有把link标签加runat=server的做法,页面多了,都比较麻烦.第二种不用考虑了,性能

ASP.NET MVC搭建项目后台UI框架—4、tab多页签支持

目录 ASP.NET MVC搭建项目后台UI框架—1.后台主框架 ASP.NET MVC搭建项目后台UI框架—2.菜单特效 ASP.NET MVC搭建项目后台UI框架—3.面板折叠和展开 ASP.NET MVC搭建项目后台UI框架—4.tab多页签支持 ASP.NET MVC搭建项目后台UI框架—5.Demo演示Controller和View的交互 在点击左侧菜单中的选项时,我希望有Extjs.EasyUI等中类似的tab页签功能,因为这样可以支持多个页面的浏览,有时候我们可能需要同时打开多个页

【转】android 欢迎界面翻页成效,仿微信第一次登陆介绍翻页界面

android 欢迎界面翻页效果,仿微信第一次登陆介绍翻页界面 本实例做的相对比较简单主要是对翻页控件的使用,有时候想要做一些功能是主要是先了解下是否有现成的控件可以使用,做起来比较简单不用费太大的劲去找别的资料,或者别的办法设计.有空多读读android API了解熟悉了做什么都比较容易.(注意:ViewPager用于实现多页面的切换效果,该类存在于Google的兼容包里面,所以在引用时记得在BuilldPath中加入“android-support-v4.jar” 如果sdk是4.0及以上的

WPF中ListBox ListView数据翻页浏览笔记(强调:是数据翻页,非翻页动画)

ListBox和ListView在应用中,常常有需求关于每页显示固定数量的数据,然后通过Timer自动或者手动翻页操作,本文介绍到的就是该动作的实现. 一.重点 对于ListBox和ListView来讲,后台绑定的ItemSource绑定的一般都是List<T>格式,而List<T>有个方法是Take和Skip,分别意思是取List部分和跳过List部分. 取数据的格式是:List.take().Skip(); 二.话不多说,实例说话(后面会附有该例子链接,仅供参考) (1)Xam

软件测试典型问题记录-修改窗口页面存在两个页签,修改后在某个页签点确定,另一页签内容未修改

容易忽视的问题记录 修改页面大概如下: 问题:修改完成后,在页签1,点击确定,修改无误: 在页签2,点击确定,页签1中的内容未做修改.

在ASP.NET MVC中使用Knockout实践07,自定义验证信息的位置与内容

在前两篇中,体验了Knockout的基本验证和自定义验证.本篇自定义验证信息的显示位置与内容. 自定义验证信息的显示位置 通常,Knockout的验证信息紧跟在input后面,通过validationMessage属性可以自定义验证信息的显示位置. @{ ViewBag.Title = "Index"; Layout = "~/Views/Shared/_Layout.cshtml"; } <style type="text/css">

java的toString是一个什么方法,为什么我在类中重写他,当输出该类对象的时候却能显示里面的结果?(转)

例如:我输出的是一个对象,却调用到了toString方法 public class TTT { private String id; private String name; public void setId(String id) { this.id = id; } public void setName(String name) { this.name = name; } public String toString() { return "学号:" + id + "\n

从BIRT报表文件中获取页面设置信息(页边距、纸张大小、输出方向)的方法

报表打印时,尤其是套打的报表,页面设置信息非常重要,比如页边距,纸张大小,输出方向等,而且每个报表的相关参数有可能不同,因此相关参数从具体报表中获取是一个非常正常而且合理的想法. 如果采用BIRT作为报表的开发工具,报表设计器负责报表的制作,BIRT运行时负责处理报表文件,对于浏览器来说,BIRT后端输出的是网页,并不包含页面设置相关信息,浏览器有自己的打印设置选项,也不会从网页中读取,但是报表设计器在报表设计时提供页面设置信息的设置界面,因此我们需要通过运行时API手工写代码从具体报表中获取页