自定義HttpResponse的Filter修改Http Entity Body


HttpResponse的Filter屬性允許開發人員定義一個派生於Stream的類型,修改Http Entity Body。比如原來的Web應用程序並沒有添加兼容性標記,許多頁面也並沒有使用Master,各處修改增加了許多工作量。編寫一個HttpModule,在Init函數中訂閱HttpApplication的ReleaseRequestState事件。

1 // <summary>
2 /// 初始化
3 /// </summary>
4 /// <param name=”context”>上下文</param>
5 public void Init(HttpApplication context)
6 {
7   context.ReleaseRequestState += new EventHandler(OnReleaseRequestState);
8 }

新建一個派生於Stream的類型HeadRequestFilter,並在ReleaseRequestState事件觸發后為HttpResponse的Filter屬性賦值:

 1 /// <summary>
 2 /// 釋放請求狀態
 3 /// </summary>
 4 /// <param name=”sender”>發送方</param>
 5 /// <param name=”e”>事件參數</param>
 6 private void OnReleaseRequestState(Object sender, EventArgs e)
 7 {
 8   HttpResponse response = HttpContext.Current.Response;
 9 
10   response.Filter = new HeadRequestFilter(response.Filter);
11 }

由於我們只需要為head標簽內添加meta標簽,所以HttpResponse原來的HttpResponseStreamFilterSink依然可以被使用。需要修改的是Stream定義的Write和Flush函數。在執行Flush函數前需要通過StringBuilder保存舊有輸出的HTML:

m_buffer.Append(HttpContext.Current.Response.ContentEncoding.GetString(buffer, offset, count));

在調用Flush函數內部插入meta標簽,最后調用HttpResponse輸出修改后的Http Entity Body。下面是一個實現插入meta標簽的HeadResponseFilter示例:

  1 public sealed class HeadResponseFilter : Stream
  2 {
  3   private const String TAG_HEAD_BEGIN = “<head”;
  4   private const String TAG_HEAD_END = “</head>”;
  5 
  6   private StringBuilder m_buffer;
  7   private Stream m_stream;
  8 
  9   /// <summary>
 10   /// 構造函數
 11   /// </summary>
 12   /// <param name=”stream”></param>
 13   public HeadResponseFilter(Stream stream)
 14   {
 15     m_stream = stream;
 16     m_buffer = new StringBuilder();
 17   }
 18 
 19   /// <summary>
 20   /// 請求
 21   /// </summary>
 22   public HttpRequest Request
 23   {
 24     get
 25     {
 26       return HttpContext.Current.Request;
 27     }
 28   }
 29 
 30   /// <summary>
 31   /// 響應
 32   /// </summary>
 33   public HttpResponse Response
 34   {
 35     get
 36     {
 37       return HttpContext.Current.Response;
 38     }
 39   }
 40 
 41   /// <summary>
 42   /// 可讀
 43   /// </summary>
 44   public override Boolean CanRead
 45   {
 46     get { return true; }
 47   }
 48 
 49   /// <summary>
 50   /// 可查詢
 51   /// </summary>
 52   public override Boolean CanSeek
 53   {
 54     get { return true; }
 55   }
 56 
 57   /// <summary>
 58   /// 可寫
 59   /// </summary>
 60   public override Boolean CanWrite
 61   {
 62     get { return true; }
 63   }
 64 
 65   /// <summary>
 66   /// 長度
 67   /// </summary>
 68   public override Int64 Length
 69   {
 70     get { return 0; }
 71   }
 72 
 73   /// <summary>
 74   /// 位置
 75   /// </summary>
 76   public override Int64 Position { get; set; }
 77 
 78   /// <summary>
 79   /// 刷新
 80   /// </summary>
 81   public override void Flush()
 82   {
 83     String rawHtml = m_buffer.ToString();
 84     Int32 headIndex = rawHtml.IndexOf(TAG_HEAD_BEGIN, StringComparison.CurrentCultureIgnoreCase);
 85     Int32 headIndex2 = rawHtml.IndexOf(TAG_HEAD_END, StringComparison.CurrentCultureIgnoreCase);
 86 
 87     if ((headIndex > 0) && (headIndex2 > 0) && (headIndex < headIndex2))
 88     {
 89       String rawHead = rawHtml.Substring(headIndex, headIndex2 – headIndex + TAG_HEAD_END.Length);
 90       XElement headElement = XElement.Parse(rawHead);
 91       IEnumerable<XElement> metaElement = headElement.Descendants(“meta”).Where(p => p.Attribute(“http-equiv”) != null);
 92 
 93       if (metaElement.Count() == 0)
 94         headElement.Add(new XElement(“meta”, new XAttribute(“http-equiv”, “x-ua-compatible”), new XAttribute(“content”, “IE=7″)));
 95 
 96       rawHtml = String.Concat(rawHtml.Substring(0, headIndex), headElement.ToString(), rawHtml.Substring(headIndex + rawHead.Length));
 97     }
 98 
 99     this.Response.Write(rawHtml);
100     this.Response.Flush();
101   }
102 
103   /// <summary>
104   /// 讀取
105   /// </summary>
106   /// <param name=”buffer”>緩沖區</param>
107   /// <param name=”offset”>偏移量</param>
108   /// <param name=”count”>數量</param>
109   /// <returns>讀取數量</returns>
110   public override Int32 Read(Byte[] buffer, Int32 offset, Int32 count)
111   {
112     return m_stream.Read(buffer, offset, count);
113   }
114 
115   /// <summary>
116   /// 查找
117   /// </summary>
118   /// <param name=”offset”>偏移量</param>
119   /// <param name=”origin”>參考點</param>
120   /// <returns>位置</returns>
121   public override Int64 Seek(Int64 offset, SeekOrigin origin)
122   {
123     return m_stream.Seek(offset, origin);
124   }
125 
126   /// <summary>
127   /// 設置長度
128   /// </summary>
129   /// <param name=”value”></param>
130   public override void SetLength(Int64 value)
131   {
132     m_stream.SetLength(value);
133   }
134 
135   /// <summary>
136   /// 寫入
137   /// </summary>
138   /// <param name=”buffer”>緩沖區</param>
139   /// <param name=”offset”>偏移量</param>
140   /// <param name=”count”>數量</param>
141   public override void Write(Byte[] buffer, Int32 offset, Int32 count)
142   {
143     m_buffer.Append(HttpContext.Current.Response.ContentEncoding.GetString(buffer, offset, count));
144   }
145 }


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM