2009-09-04 62 views
9

這裏是我特別試圖做的:如何從HttpModule中檢索響應html?

我寫了一個HttpModule來做一些特定的站點跟蹤。我們網站上的一些舊的.aspx頁面是硬編碼的,沒有真正的控件,但它們是.aspx文件,因此我的模塊在請求時仍然運行。

我的模塊的處理程序連接到PostRequestHandlerExecute,所以我相信會發回給請求者的東西應該已經確定了。

我需要能夠提取標題標籤中的任何字符串。

所以,如果

<title>Chunky Bacon</title> 

在最終渲染HTML格式發送給請求者。然後我想要「矮胖培根」。

想法?

+0

你是什麼意思「提取任何字符串在標籤中」?您是否試圖操縱回覆給請求者的回覆?目前尚不清楚你想要做什麼。 – NerdFury 2009-09-04 17:32:01

+0

對不起,我忘記了我的HTML標籤不會顯示出來,除非我把它放在一個代碼塊中。我不需要操縱響應,只需在標題標籤內提取字符串即可。 – spilliton 2009-09-04 17:53:40

+0

要澄清,您是否試圖從響應中獲取內容或嘗試從內容中解析標記? – 2009-09-04 18:01:20

回答

22

有趣的小挑戰。

下面的代碼:

StreamWatcher.cs

public class StreamWatcher : Stream 
    { 
     private Stream _base; 
     private MemoryStream _memoryStream = new MemoryStream(); 

     public StreamWatcher(Stream stream) 
     { 
      _base = stream; 
     } 

     public override void Flush() 
     { 
      _base.Flush(); 
     } 

     public override int Read(byte[] buffer, int offset, int count) 
     { 
      return _base.Read(buffer, offset, count); 
     } 

     public override void Write(byte[] buffer, int offset, int count) 
     { 
      _memoryStream.Write(buffer, offset, count); 
      _base.Write(buffer, offset, count); 
     } 

     public override string ToString() 
     { 
      return Encoding.UTF8.GetString(_memoryStream.ToArray()); 
     } 

     #region Rest of the overrides 
     public override bool CanRead 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public override bool CanSeek 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public override bool CanWrite 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public override long Seek(long offset, SeekOrigin origin) 
     { 
      throw new NotImplementedException(); 
     } 

     public override void SetLength(long value) 
     { 
      throw new NotImplementedException(); 
     } 

     public override long Length 
     { 
      get { throw new NotImplementedException(); } 
     } 

     public override long Position 
     { 
      get 
      { 
       throw new NotImplementedException(); 
      } 
      set 
      { 
       throw new NotImplementedException(); 
      } 
     } 
     #endregion 
    } 

TitleModule.cs

public class TitleModule : IHttpModule 
{ 
    public void Dispose() 
    { 
    } 

    private static Regex regex = new Regex(@"(?<=<title>)[\w\s\r\n]*?(?=</title)", RegexOptions.Compiled | RegexOptions.IgnoreCase); 
    private StreamWatcher _watcher; 
    public void Init(HttpApplication context) 
    { 
     context.BeginRequest += (o, e) => 
     { 
      _watcher = new StreamWatcher(context.Response.Filter); 
      context.Response.Filter = _watcher; 
     }; 


     context.EndRequest += (o, e) => 
     { 
      string value = _watcher.ToString(); 
      Trace.WriteLine(regex.Match(value).Value.Trim()); 
     }; 
    } 
} 
+0

這就行了,謝謝broseph! 我仍然超級驚訝這需要很多代碼行來執行... – spilliton 2009-09-04 21:35:23

+0

優秀的解決方案! – gljivar 2011-06-28 21:41:03

+0

對於4.6.1 AFAIK,您必須實現引發NotImplementedException的方法。最簡單的方法是將所有的調用推遲到_memoryStream – 2016-09-16 00:37:05

3

上有4GuysFromRolla,討論有關創建過濾器的HttpResponse這是一個項目基本上是在passi之前處理響應的流通過它到最後的輸出流(一個攔截器)。

http://aspnet.4guysfromrolla.com/articles/120308-1.aspx

+0

很酷,在尋找解決方案時,我在google上閱讀了一些關於這些內容的文章,似乎編寫這些解決方案的主要目的是操縱HTML在發送之前發送。由於我不操縱,只需要訪問HTML,我認爲這將是矯枉過正,但如果它是唯一的方法...... – spilliton 2009-09-04 18:24:18