2009-02-22 58 views
1

我試圖找到一個事件,將在所有事件處理程序全部觸發後立即觸發,以便我可以修改發送的響應(與狀態碼和'位置'標題混合並創建一個新的主體特別是)使用自定義的HttpModule。ASP.NET Post Application_Error事件

我試圖鉤住Application_EndRequest(如我讀過,這是保證射擊的唯一處理器),但是這是在請求處理來不及修改響應頭和我得到了HttpException

Server cannot append header after HTTP headers have been sent. 

回答

2

我認爲ASP.Net在ApplicationError之後啓動一個新的響應,只是針對不同的錯誤處理頁面。嘗試加入這個迴應。

更新好的:這是怎麼做到的!

我想確保我們都可以附加一個錯誤處理程序,並且我們可以優雅地處理頁面中的事件,所以我們不能讓最後一個服務器錯誤爲空,而且我們也希望能夠添加標題!

在web.config中,添加:

<customErrors redirectMode="ResponseRewrite" mode="On"> 
    <error statusCode="500" redirect="~/ErrorHandler.aspx"/> 
</customErrors> 

或者任何錯誤。特別是你正在尋找捕捉。而下的HttpModules:

<add name="ErrorModule" type="TestErrorLifecycle.ErrorModule, TestErrorLifecycle"/> 

的代碼記錄錯誤是在此模塊中:

public class ErrorModule : IHttpModule 
{ 
    private volatile object locker = new object(); 

    public void Init(HttpApplication context) 
    { 
     context.Error += context_Error; 
    } 

    void context_Error(object sender, EventArgs e) 
    { 
     var app = sender as HttpApplication; 

     lock (locker) 
     { 
      assertLogDirectory(app.Server); 

      using (var fs = File.AppendText(app.Server.MapPath("~/logs/errorlog.txt"))) 
      { 
       var lastException = app.Server.GetLastError(); 
       if (lastException == null) throw new ApplicationException("Not expected..."); 
       fs.WriteLine(lastException.Message); 
      } 
     } 

     // we could also do a Request.Redirect() here... 
    } 

    private void assertLogDirectory(HttpServerUtility server) 
    { 
     var logdir = server.MapPath("~/logs/"); 
     if (!Directory.Exists(logdir)) 
      Directory.CreateDirectory(logdir); 
    } 

    public void Dispose() 
    { 
    } 
} 

我剛寫入的文件系統。你可以使用內核文件事務或獨佔鎖等等,但是因爲我知道我只會從這裏寫入這個文件,所以我選擇了一個簡單的私有信號量。

我說這只是Default.aspx.cs測試:

protected void Page_Load(object sender, EventArgs e) 
{ 
    throw new ApplicationException("wtf, something wrong??!"); 
} 

創造了這個在它的文件ErrorHandler.aspx(部分省略急促):

<body> 
    <h2>Error handler</h2> 
    <form id="form1" runat="server"> 
     <p>Last error: <asp:Label ID="lblError" runat="server" /></p> 
    </form> 
</body> 

而這裏的頁面級:

public partial class ErrorHandler : Page 
{ 
    public ErrorHandler() 
    { 
     Load += ErrorHandler_Load; 
    } 

    private void ErrorHandler_Load(object sender, EventArgs e) 
    { 
     Response.AddHeader("X-TESTING", "Yes it works..."); 
     lblError.Text = Server.GetLastError() == null ? "noo, why is it null?!?" : Server.GetLastError().Message; 
    } 
} 

最後,我在ErrorHandler.aspx得到這些響應頭:

Server: ASP.NET Development Server/9.0.0.0 
Date: Mon, 23 Feb 2009 00:37:45 GMT 
X-AspNet-Version: 2.0.50727 
X-TESTING: Yes it works... 
Cache-Control: private 
Content-Type: text/html; charset=utf-8 
Content-Length: 725 
Connection: Close 
200 OK 

如果您嘗試添加到Response.Headers收集直接需要在管道模式下運行IIS:http://forums.asp.net/p/1253457/2323117.aspx

我希望這有助於! Cheers Henrik

+0

你有什麼關於如何去做這件事的指針? – 2009-02-23 00:03:00

+0

是的,我會進行測試。 – Henrik 2009-02-23 00:08:09

0

除非您在發送任何響應之前移動所有容易出錯的代碼,否則您將無法解決此問題。如果你想這樣做,你需要設置一個HttpHandler來處理所有的代碼,然後將任何信息發送回客戶端。

有許多方法可以重新構建以將信息重新發回客戶端。知道應用程序在哪裏爆炸並通過try ... catch來運行它將有所幫助。

相關問題