2013-06-18 30 views
1

我正在爲我們的asp.net mvc 3應用程序添加錯誤處理。基本上我想抓住每一個未經處理的錯誤,以防核爆炸。哪裏是捕獲所有ASP.NET MVC錯誤附加適當的地方?

我已經確定了這樣做的以下點:

  • 控制器基類(我所有的控制器來自同一個基類派生所以這是可行的)
  • HandleErrorAttributeOnException與客戶視圖,在處理web.config中Global.asax
  • 打開<customErrors mode="On">異常
  • Application_Error事件,並設置將處理異常的自定義URL。

我對這些地方它們之間是如何關聯一個非常模糊的概念,並希望有人來解釋的差異,以及爲什麼有擺在首位這麼多的。

另外,我應該使用哪一個(或全部?)?他們有些是多餘的?是否有例外可以被一個人捕獲,但不被其他人捕獲?如果即使這些都失敗了,會發生什麼情況(比如,最後一種異常處理程序方法本身會導致異常)?

回答

1
  • onException的在基本控制器沒有捕捉所有的錯誤 (特別是如果不是所有的控制器繼承它)。

  • HandleErrorAttribute將需要您逐個應用該屬性。或者使用全局過濾器應用它,但它對所有控制器都是一樣的。

  • 關閉customErrors將只顯示錯誤,不處理它。而且您無法爲不同類型的錯誤提供不同的視圖。

我們通常做的是這樣的:

安裝ELMAH或類似的包裝,以保持所有錯誤的軌道,即使他們默默發生。

然後,在Global.asax中:

protected void Application_Error(object sender, EventArgs e) 
{ 
    //Retrieving the last server error 
    var exception = Server.GetLastError(); 

    //Erases any buffered HTML output 
    Response.Clear(); 

    var httpException = exception as HttpException; 

    var routeData = new RouteData(); 
    routeData.Values.Add("controller", "Error"); //Adding a reference to the error controller 
    if (httpException == null) 
    { 
     routeData.Values.Add("action", "ServerError"); //Non HTTP related error handling 
    } 

    else //It's an Http Exception, Let's handle it. 
    { 
     switch (httpException.GetHttpCode()) 
     { 
      case 401: 
      case 403: 
       //Forbidden page. 
       routeData.Values.Add("action", "Forbidden"); 
       break; 
      case 404: 
       //Page not found. 
       routeData.Values.Add("action", "NotFound"); 
       break; 
      case 500: 
       routeData.Values.Add("action", "ServerError"); 
       break; 
      default: 
       routeData.Values.Add("action", "Index"); 
       break; 
     } 
    } 

    //Pass exception details to the target error View. 
    routeData.Values.Add("message", exception); 

    //Clear the error on server. 
    Server.ClearError(); 

    //Avoid IIS7 getting in the middle 
    Response.TrySkipIisCustomErrors = true; 

    // Call target Controller and pass the routeData. 
    IController errorController = new ErrorController(); 
    errorController.Execute(new RequestContext(
     new HttpContextWrapper(Context), routeData)); 
}   

我們覺得這是給我們在處理大多數控制和如何展現我們的遊客的選項。所顯示的每個操作(servererror,notfound和forbidden)都有不同的屏幕,並且取決於服務器是在調試還是釋放時運行,那麼我們將顯示堆棧跟蹤信息與否(但我們始終使用ELMAH捕獲它,以便始終可以看到它有)

+0

Elmah很棒,但有一些缺陷 - 它不會捕獲WCF服務錯誤,以及StackOverflowException和OutOfMemoryException。 –

+0

@OndrejSvejdar - 無論如何StackOverflow和OutOfMemory幾乎都是不可恢復的,所以如果沒有發現它們就沒關係。 –

+0

我的控制器都是從同一個類繼承的,我正在尋找一個全局解決方案。那麼爲什麼有'OnException'和'HandleErrorAttribute',如果我可以在'Application_Error'中做所有事情?有兩個重定向位置('customErrors'和'HandleErrorAttribute')有什麼意義? –

相關問題