2013-10-29 70 views
2

我正在構建一個ASP.NET Web Api服務,我想創建集中的異常處理代碼。如何不在ASP.NET Web Api服務中拋出異常?

我想以不同的方式處理不同類型的異常。我將使用log4net記錄所有異常。對於某些類型的例外,我將通過電子郵件通知管理員。對於某些類型的例外,我想重新拋出一個友好的異常,並將其返回給調用者。對於某些類型的例外,我想繼續從控制器進行處理。

但我該怎麼做?我正在使用一個例外過濾器屬性。我有這個代碼工作。該屬性已正確註冊並且代碼正在觸發。我只想知道如果拋出某些類型的異常,我該如何繼續。希望這是有道理的。

public class MyExceptionHandlingAttribute : ExceptionFilterAttribute 
{ 
    public override void OnException(HttpActionExecutedContext actionExecutedContext) 
    { 
    //Log all errors 
    _log.Error(myException); 

    if(myException is [one of the types I need to notify about]) 
    { 
     ...send out notification email 
    } 

    if(myException is [one of the types that we continue processing]) 
    { 
     ...don't do anything, return back to the caller and continue 
     ...Not sure how to do this. How do I basically not do anything here? 
    } 

    if(myException is [one of the types where we rethrow]) 
    { 
     throw new HttpResponseException(new HttpResponseMessage(StatusCode.InternalServerError) 
     { 
     Content = new StringContent("Friendly message goes here."), 
     ReasonPhrase = "Critical Exception" 
     }); 
    } 
    } 
} 
+0

異常過濾器僅在WebAPI消息管道的「返回」部分中被觸發。所以,如果你依靠異常過濾器來處理你的異常,我不認爲有一個簡單的方法讓請求重新進入管道進行進一步處理。有關WebAPI擴展點的更多信息,請參閱[MVC海報](http://www.asp.net/posters/web-api/ASP.NET-Web-API-Poster.pdf)。 –

回答

2

對於某些類型的異常我只想繼續從控制器處理。但我該怎麼做?

通過書寫try..catch您希望發生此行爲的位置。請參閱Resuming execution of code after exception is thrown and caught

爲了澄清,我假設你有這樣的事情:

void ProcessEntries(entries) 
{ 
    foreach (var entry in entries) 
    { 
     ProcessEntry(entry); 
    } 
} 

void ProcessEntry(entry) 
{ 
    if (foo) 
    { 
     throw new EntryProcessingException(); 
    } 
} 

EntryProcessingException被拋出時,你其實並不關心,並希望繼續執行。


如果這個假設是正確的:你不能這樣做,有一個全球性的異常過濾器,因爲一旦一個異常被抓住了,有沒有執行返回到它被拋出。 C#中的There is no On Error Resume Next,尤其是當使用過濾器處理異常時,特別是@Marjan explained

所以,從過濾器去除EntryProcessingException,並通過改變循環體趕上特例:

void ProcessEntries(entries) 
{ 
    foreach (var entry in entries) 
    { 
     try 
     { 
      ProcessEntry(entry); 
     } 
     catch (EntryProcessingException ex) 
     { 
      // Log the exception 
     } 
    } 
} 

而且你的循環將愉快地旋轉到其結束,但是扔在所有其他異常的地方將是由您的過濾器處理。

+0

嘗試除了不會執行,因爲Exception過濾器可以看作是「應用程序全局異常捕獲器」的一種類型,並且不會(容易地)允許進一步處理該消息,這看起來是OP之後的事情。 –

+0

@Marjan OP對於特定的例外似乎想要一個「On Error Resume Next」。你不能在那個沒有'try..catch'的情況下爲那個調用站點中的特定異常做這件事,因爲如果你沒有捕獲到這個異常,而是讓它被一個過濾器處理,那麼就沒有回到它被拋出的地方。 – CodeCaster

+0

我知道,但try catch無法幫助他做任何事情:在單個位置執行所有異常處理:異常過濾器。異常過濾器由WebAPI框架觸發,作爲對「用戶代碼」引發的異常的響應。 –

相關問題