2012-01-01 27 views
-1

我問過關於創建IIS日誌記錄器的一個問題,但我仍然有幾個問題:IHttpModule的問題

  1. 原始郵件丟失
  2. 響應消息沒有捕捉到

完全可以將這2個問題整理出來嗎?

的IHttpHandler:

using System.Web; 
using System.IO; 

namespace MyLogger 
{ 
    public class MyHandler : IHttpHandler 
    { 
     public void ProcessRequest(HttpContext context) 
     { 
      context.Response.Write("The page request is " + context.Request.RawUrl.ToString()); 
      StreamWriter sw = new StreamWriter(@"C:\requestLog.txt", true); 
      sw.WriteLine("Page requested at " + DateTime.Now.ToString() + context.Request.RawUrl); 
      sw.Close(); 
     } 

     public bool IsReusable 
     { 
      get 
      { 
       return true; 
      } 
     } 
    } 
} 

的IHttpModule:

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Web; 
using System.IO; 

namespace MyLogger 
{ 
    public class MyModule : IHttpModule 
    { 
     public InterceptorModule() 
     { } 
     public void Init(HttpApplication objApplication) 
     { 
      // Register event handler of the pipe line 
      objApplication.BeginRequest += new EventHandler(this.ContextBeginRequest); 
      objApplication.EndRequest += new EventHandler(this.ContextEndRequest); 
     } 
     public void Dispose() 
     { 
     } 
     public void ContextEndRequest(object sender, EventArgs e) 
     { 
      StreamWriter sw = new StreamWriter(@"C:\requestLog.txt", true); 
      sw.WriteLine("End Request called at " + DateTime.Now.ToString()); sw.Close(); 
     } 
     public void ContextBeginRequest(object sender, EventArgs e) 
     { 
      StreamWriter sw = new StreamWriter(@"C:\requestLog.txt", true); 
      sw.WriteLine("Begin request called at " + DateTime.Now.ToString()); sw.Close(); 
     } 
    } 
} 

我以前的帖子:IIS API Monitor in a web application 提前感謝!

+2

你* *嚴重WO左右在多線程環境中使用單個物理文件*這種方式*? – 2012-01-01 23:20:18

+0

請務必在您的其他問題中標記您的答案,以便將來的讀者可以從您的經驗中學習。 – 2012-01-01 23:31:37

+0

爲了簡單起見,我只是把它放在那裏。我的問題與多線程無關,這就是爲什麼我將它排除在外的原因。無論如何,我確實將答案標記爲有用,但由於某種原因,它沒有反映在頁面上。我確實在評論部分留下了我的發現以備將來參考。 – Raytrace 2012-01-02 06:42:49

回答

1

我不確定HTTPHandler是什麼,但所有的日誌記錄都可以從HTTPModule執行。然而,爲了生存,你的代碼需要一些實質性的改進。

1)你應該在streamwriters周圍設置try/catch塊,以確保不會引發未處理的異常,尤其是當你試圖不顯眼時。

2)Streamwriter代碼應該包裝在一個使用塊中,以確保您不會分享資源。

3)由於您可能有多個線程試圖同時寫入文件,因此您需要將寫入代碼封裝在鎖定塊中。

4)您可以使用HttpContext.Current.Request來訪問當前的請求,我懷疑這可能是您在HttpModule中所做的。如果這不是這個意圖,我們將需要進一步澄清。 5)如果以調試模式啓動應用程序,並且Init方法未被命中,那麼您的web.config條目不正確。該類型必須是完全合格的(即包括命名空間),你應該同時添加綜合類模式配置:

經典模式(IIS 6,IIS 7 +經典)

<configuration> 
    <system.web> 
    <httpModules> 
     <add name="MyModule" type="MyNamespace.MyModule"/> 
    </httpModules> 
    </system.web> 
</configuration> 

集成模式(IIS 7+集成)

<configuration> 
    <system.webServer> 
    <modules> 
     <add name="MyModule" type="MyNamespace.MyModule"/> 
    </modules> 
    </system.webServer> 
</configuration> 

這裏是重寫代碼:

static Object m_LockObject = new Object(); 

    public void Init(HttpApplication objApplication) 
    { 
     // Register event handler of the pipe line 
     objApplication.BeginRequest += new EventHandler(this.ContextBeginRequest); 
     objApplication.EndRequest += new EventHandler(this.ContextEndRequest); 
    } 
    public void ContextEndRequest(object sender, EventArgs e) 
    { 
     try 
     { 
      lock (m_LockObject) 
      { 
       using (StreamWriter sw = new StreamWriter(@"C:\requestLog.txt", true)) 
       { 
        sw.WriteLine("End request called at " + DateTime.Now.ToString() + "; URL: " + HttpContext.Current.Request.RawUrl.ToString()); 
       } 
      } 

      // Write the response back to the caller 
      HttpContext.Current.Response.Write("The page request is " + HttpContext.Current.Request.RawUrl.ToString()); 

     } 
     catch 
     { 
     } 
    } 
    public void ContextBeginRequest(object sender, EventArgs e) 
    { 
     try 
     { 
      lock (m_LockObject) 
      { 
       using (StreamWriter sw = new StreamWriter(@"C:\requestLog.txt", true)) 
       { 
        sw.WriteLine("Begin request called at " + DateTime.Now.ToString() + "; URL: " + HttpContext.Current.Request.RawUrl.ToString()); 
       } 
      } 
     } 
     catch 
     { 
     } 
    } 
+0

感謝您的回覆,但它並未解決我需要將原始郵件記錄並轉發給呼叫客戶端的問題。用HttpModule和/或HttpHandler可以做到這一點嗎? – Raytrace 2012-01-02 06:46:19

+0

@Raytrace:是的,這絕對可以使用'HttpContext.Current.Response.Write'完成。對不起,我錯過了原來的httpmodule。我已經更新了答案,以便在「ContextEndRequest」中完成,因此它出現在頁面的底部。 – 2012-01-02 17:40:24

+0

在這裏找到我的答案供將來參考:http://forums.asp.net/post/2417324.aspx – Raytrace 2012-01-03 00:09:13