2012-04-23 115 views
11

我會從開始,是的,我們已經創建並正在使用從ExceptionFilterAttribute繼承的異常過濾器。它是在我們的身份過濾器之後的應用程序啓動配置中註冊的,並且如果在我們的API中發生錯誤時發生錯誤,它的工作方式與預期相當。異常處理ASP.NET MVC Web API

這就是說,我正在尋找一種方法來處理在它到達API之前發生的錯誤。

推理:我們從不想要返回YSOD和/或IIS HTML錯誤。我們總是要打一個自定義異常過濾器/處理程序,以便我們可以正確處理日誌記錄並向用戶返回JSON響應。

截至目前,使用Fiddler發出請求,我可以附加到w3wp.exe進程,並看到請求在Global.asax中找到了Application_BeginRequest方法。之後,它只是返回500響應。它從來沒有在代碼中打破例外,或者在那之後觸發我的任何斷點。它似乎正在返回一個IIS錯誤。我們永遠不希望發生這種情況。我們需要能夠捕獲所有這些「低級」異常,記錄它們,並向用戶返回有意義的內容。

有什麼我們可以做的處理錯誤之前,什麼似乎是擊中ASP.NET MVC Web API代碼?

+0

這種感覺錯了。你是否在某個庫中拋出異常?爲什麼不在控制器中捕獲異常並返回您自己選擇的錯誤視圖? – 2012-04-23 16:48:41

+1

這是使用ASP.NET MVC Web API,所以我們沒有從控制器返回視圖。我們返回JSON/XML響應。我在我的問題中還提到,在他們到達控制器之前,我需要一種處理異常的方法。現在我們擁有一個ExceptionFilter,一旦我們進入控制器,就可以在任何地方捕獲異常,所以我們不必在每個操作中都有try/catch。 – phreak3eb 2012-04-23 18:23:20

+0

我不認爲我完全理解你的問題。你試圖準確捕捉什麼類型的錯誤? – cecilphillip 2012-04-23 19:05:21

回答

4

儘管我喜歡Darin的答案,但它並不適用於我們的情況,因爲ASP.NET MVC Web API框架在內部抑制/處理異常,而不是重新拋出以觸發Global.asax中的Application_Error方法。我們的解決方案是

我結束了創建自定義DelegatingHandler像這樣:

public class PrincipalHandler : DelegatingHandler 
{ 
    protected const string PrincipalKey = "MS_UserPrincipal"; 
    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) 
    { 
     setAnonymousPrincipal(); 

     request = InitializeIdentity(request); 

     return base.SendAsync(request, cancellationToken) 
      .ContinueWith(r => 
           { 
            // inspect result for status code and handle accordingly 
            return r.Result; 
           }); 
    } 
} 

我那麼插入它到HttpConfiguration,以確保它是第一個/最後一個處理程序被擊中。處理程序在Web API中的工作方式是分層次的。因此,第一個處理器將按照請求進行處理,將成爲響應中最後一個處理器。至少這是我的理解,如果我錯了,有人可以隨時糾正我。

public static void ConfigureApis(HttpConfiguration config) 
{ 
    config.MessageHandlers.Insert(0, new PrincipalHandler()); 
} 

通過使用這種方法,我們現在可以檢查來自Web API和控制器的任何響應中返回的每個結果。這使我們能夠處理任何可能需要發生的日誌記錄,這些日誌記錄不會像我們預期的那樣返回。我們現在還可以更改返回的響應內容,以便IIS在看到某些HTTP狀態代碼時不會插入任何默認的HTML錯誤頁面。

我有這個唯一的問題,我希望他們改變它即將發佈的Web API,是他們不會發送異常備份在從base.SendAsync返回的任務( )。因此,我們唯一需要的信息就是HTTP狀態代碼,並盡力爲消費者提供合理或可能的答案。

+0

對於任何正在尋找關於調用'config.MessageHandlers.Insert()'的文檔的文檔,都可以[在WebAPI文檔中](http://www.asp.net/web-api/overview/working-with -http/HTTP的消息處理程序)。 – 2012-05-17 18:15:50

+1

如果您想要Web API中的全局錯誤處理程序以及完整的例外信息,請在http://aspnetwebstack.codeplex.com/workitem/1001上投票選擇此功能。 – 2013-05-09 00:57:49

+0

這看起來也是一個方便的變體:http:// blog.codeishard.net/2013/02/09/webapi-and-the-behavior-of-exceptions-and-an-alternative-configurable-way-to-deal/ – CrazyPyro 2013-09-20 23:13:30