我想用httpmodule或者httphandler对所有aspnet输出的内容进行过滤,但是遇见了问题,我无法把Response里的东西获取出来,后来发现只能在BeginRequest的时候给Response加入一个Response.Filter的过滤器后,在过滤器中实现,但又引起了一个新问题BeginRequest的时候我无法知道最终Response的时候会输出一个什么样的东西,是一个页面?还是一个动态生成的图片(比如校验码)如果是图片的话,经过我的过滤处理,图片受到了损坏,造成无法显示请问各位达人,我该怎么办才好?前提是必须用httpmodule或者httphandler,不能使用页面基类去重写Render方法来实现。对了,我曾经试图,在过滤器中将原本的Stream保存一个副本,在EndRequest的时候已经知道Reponse的类型了,判断是图片的话,进行还原,也宣布失败,我也曾怀疑,是我的过滤器的编码方式或者别的什么导致的图片损坏,但不知道如何做才能不损坏贴个代码,大家帮忙看看,先谢啦。            string PageContent = Encoding.GetString(buffer, offset, count);            foreach (TextReplaceRules MyTextReplaceFilterRules in ReplaceRules)
            {
                PageContent = PageContent.Replace(MyTextReplaceFilterRules.OriginText, MyTextReplaceFilterRules.ResultText);
            }            byte[] bytePageContent = Encoding.GetBytes(PageContent);            m_stream.Write(bytePageContent, offset, count);
---------------------
上面进行替换的内容MyTextReplaceFilterRules.OriginText, MyTextReplaceFilterRules.ResultText基本没什么问题,即便不替换也会出问题,所以和这里应该没关系编码方式我试过了ASC2和UTF-8

解决方案 »

  1.   

    hdt在Request开始的时候,还没办法确定Response的ContentType,需要到RequestEnd的时候,Reponse的ContentType属性才能建立,但那时候加过滤器又将无效。
      

  2.   

    Response中的东西是无法获取的,不过可以通过Module来操控页面达到你想要的效果。
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Web;namespace Ivony.Web
    {
      /// <summary>
      /// 控制aspx页面的HttpModule通用基类
      /// </summary>
      public abstract class PageModule : IHttpModule
      {    private HttpApplication _application;    /// <summary>
        /// 销毁PageModule实例。
        /// </summary>
        public void Dispose()
        {
        }    /// <summary>
        /// 实现IHttpModule,初始化PageModule
        /// </summary>
        /// <param name="context">HttpApplication实例</param>
        public virtual void Init( HttpApplication context )
        {
          _application = context;      //_application.PostMapRequestHandler += new EventHandler( OnPostMapRequestHandler );
          _application.PreRequestHandlerExecute += new EventHandler( OnPreRequestHandlerExecute );
          _application.PostRequestHandlerExecute += new EventHandler( OnPostRequestHandlerExecute );    }    private void OnPreRequestHandlerExecute( object sender, EventArgs e )
        {
          _page = Context.Handler as System.Web.UI.Page;      if ( _page != null && !( _page is IDontExecutePageModule ) )
            OnPrePageExecute( sender, e );    }    /// <summary>
        /// 当执行页面处理程序之前发生
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">事件参数</param>
        protected virtual void OnPrePageExecute( object sender, EventArgs e )
        {    }
        private void OnPostRequestHandlerExecute( object sender, EventArgs e )
        {
          if ( _page != null && !( _page is IDontExecutePageModule ) )
            OnPostPageExecute( sender, e );
        }    /// <summary>
        /// 当执行页面处理程序执行完毕时发生
        /// </summary>
        /// <param name="sender">事件源</param>
        /// <param name="e">事件参数</param>
        protected virtual void OnPostPageExecute( object sender, EventArgs e )
        {    }
        private System.Web.UI.Page _page;    /// <summary>
        /// 获取当前请求的页面对象
        /// </summary>
        protected System.Web.UI.Page Page
        {
          get { return _page; }
        }    /// <summary>
        /// 获取当前的请求的Http上下文信息
        /// </summary>
        protected HttpContext Context
        {
          get { return _application.Context; }
        }    /// <summary>
        /// 获取模块所在的HttpApplication实例
        /// </summary>
        protected HttpApplication ApplicationInstanse
        {
          get { return _application; }
        }
      }
    }
      

  3.   

    Ivony,response的东西无法获取,我前天通过反编译.net fw相关的类已经知道了,你这样的做法,似乎需要修改Page相关的东西,如果是那样,就可以更简单了,直接重写Render就可以轻松实现,我现在的问题在于不能修改任何页面,却需要对所有的输出进行控制。好在Response有个过滤器可以用,昨天我也就试过了,挺好用的,控制力挺强,但关键就是这个过滤器的加载阶段,我之前一直弄错了,老在Request的开始和结束两个阶段倒腾,却忽略了一个最简单的事实,还有其他阶段的嘛!!!最后我在上下文中发现了一个叫做“ReleaseRequestState”的事件,这个事件对我来说十分合适,他处于完成了请求处理,预备输出的这么个阶段,这时候,Response有了最终的ContentType,但输出的内容还没有进行写入,Response.Filter的加载也不算晚,于是,问题解决了,呵呵,谢谢大家的建议,顺便贴出代码,与大家共享吧。
      

  4.   

    using System;
    using System.Text;
    using System.Web;
    using System.Web.UI;
    using System.Web.Caching;
    using System.Configuration;
    using System.Xml.Serialization;namespace Cnlamar.Web.HttpModule
    {
        public class TextReplace : IHttpModule
        {
            #region IHttpModule Members        public void Dispose()
            {
            }        public void Init(HttpApplication context)
            {
                context.ReleaseRequestState += new EventHandler(context_EndRequest);
            }        public void context_EndRequest(object sender, EventArgs e)
            {
                HttpApplication application = (HttpApplication)sender;            if (application.Response.ContentType.ToLower().IndexOf("image") <= -1)
                {
                    TextReplaceFilter MyTextReplaceFilter = new TextReplaceFilter(application.Response.Filter);
                    MyTextReplaceFilter.Encoding = application.Response.ContentEncoding;
                    MyTextReplaceFilter.ReplaceRules = TextReplaceConfiguration.GetConfig().Rules;
                    application.Response.Filter = MyTextReplaceFilter;
                }
            }
            #endregion
        }    class TextReplaceFilter : System.IO.Stream
        {
            public bool IsRestore = false;        private System.IO.Stream m_stream;
            private long m_position;        public TextReplaceFilter(System.IO.Stream InputStream)
            {
                m_stream = InputStream;
            }        public TextReplaceRulesCollection ReplaceRules
            {
                get
                {
                    return _ReplaceRules;
                }
                set
                {
                    _ReplaceRules = value;
                }
            }
            private TextReplaceRulesCollection _ReplaceRules;        public System.Text.Encoding Encoding
            {
                get
                {
                    return _Encoding;
                }
                set
                {
                    _Encoding = value;
                }
            }
            System.Text.Encoding _Encoding = System.Text.Encoding.UTF8;        public override bool CanRead
            { get { return true; } }        public override bool CanSeek
            { get { return false; } }        public override bool CanWrite
            { get { return false; } }        public override long Length
            { get { return 0; } }        public override long Position
            {
                get { return m_position; }
                set { m_position = value; }
            }        public override long Seek(long offset, System.IO.SeekOrigin direction)
            {
                return 0;
            }        public override void SetLength(long length)
            {
                m_stream.SetLength(length);
            }        public override void Close()
            {
                m_stream.Close();
            }        public override void Flush()
            {
                m_stream.Flush();
            }        public override int Read(byte[] buffer, int offset, int count)
            {
                return m_stream.Read(buffer, offset, count);
            }        public override void Write(byte[] buffer, int offset, int count)
            {
                string PageContent = Encoding.GetString(buffer, offset, count);            foreach (TextReplaceRules MyTextReplaceFilterRules in ReplaceRules)
                {
                    PageContent = PageContent.Replace(MyTextReplaceFilterRules.OriginText, MyTextReplaceFilterRules.ResultText);
                }            //System.Text.RegularExpressions.Regex regex;
                //foreach (TextReplaceRules MyTextReplaceFilterRules in ReplaceRules)
                //{
                //    regex = new System.Text.RegularExpressions.Regex(MyTextReplaceFilterRules.OriginText);
                //    PageContent = regex.Replace(PageContent, MyTextReplaceFilterRules.ResultText);
                //}            byte[] bytePageContent = Encoding.GetBytes(PageContent);            m_stream.Write(bytePageContent, offset, bytePageContent.Length);
            }
        }