2017-10-18 292 views
-1

我們目前的許多控制器是這樣的:處理異常

[HttpPost] 
public List<Foo> Post([FromBody]Bar model) 
{ 
    if (model == null) 
    { 
     throw new ArgumentNullException(); 
    } 

    try 
    { 
     // business logic 
    } 
    catch (Exception ex) 
    { 
     // logging 
    } 

    return dto; 
} 

大量的代碼正在這裏雖然重複。我想要做的是實現一個基本的控制器來處理異常,所以我可以返回標準化反應ErrorPayload領域,Success,等

此前.NET的核心,這是可以通過提供覆蓋OnException但是,這似乎不適用於.net核心API控制器。當我的控制器主體發生錯誤時,如何合併此異常邏輯以返回自定義響應?

我想此,作爲起點:

[HttpPost] 
public StandardFoo Post([FromBody]Bar model) 
{ 
    if (model == null) 
    { 
     throw new ArgumentNullException(); 
    } 

    // business logic 

    return new StandardFoo(){Payload: dto}; 
} 

凡異常,由模型驗證或business logic冒泡一些的邏輯塊與包含異常細節的屬性返回一個新StandardFoo拋出。

+0

documentation:https://docs.microsoft.com/en-us/aspnet/core/fundamentals/error-handling – Nkosi

+1

您正在關注錯誤的方法。你應該避免使用基於控制器的異常處理方法,以及控制器中的try catch。應儘可能保持管理者的精益,並將責任合併到另一個班級中。這似乎是[XY問題](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem)。 – Nkosi

+0

@Nkosi你能否提供一個簡單而簡潔的例子,說明如何在拋出異常時使用上述控制器並返回自定義響應? – user666

回答

1

我會建議創建一個自定義操作過濾器。這可以在WebApiConfig寄存器方法中的每個傳入請求中進行打包(請參見下文)。

在我的示例中,我檢查模型狀態是否有效。

如果不是,我創建一個ErrorResponse併發回一個錯誤的請求。

您不必像下面的例子那樣簡單地發回模型狀態,就可以返回任何你想要的東西。

通過這種方式,在所有端點上都具有需要驗證的模型以及此時在管道中執行的任何其他檢查的統一。

注意:因爲我們正在全局註冊此屬性,所以我們不必在其他任何地方聲明它,從這一點開始,所有傳入流量都將由此類進行檢查。

public class ValidateModelAttribute : ActionFilterAttribute 
     { 
      public override void OnActionExecuting(HttpActionContext actionContext) 
      { 

       if (!actionContext.ModelState.IsValid) 
       { 
        actionContext.Response = actionContext.Request.CreateErrorResponse(HttpStatusCode.BadRequest, actionContext.ModelState); 
       } 
      } 

      public override bool AllowMultiple 
      { 
       get { return false; } 
      } 
     } 



public static class WebApiConfig 
    { 
     public static void Register(HttpConfiguration config) 
     { 
      // Web API configuration and services 
      config.Filters.Add(new ValidateModelAttribute()); 
     } 
    } 
2

如果不久,您就不應該捕獲並處理控制器中的異常。


相反,您需要在代碼中分開正常流和錯誤流,然後分別處理錯誤流。指示正常流程不可行的主要方法之一是提出.NET異常(並使用它)。但是:

  • 控制器操作應該只知道正常流量。沒有try-catch邏輯等等。
  • 用於輸入驗證使用ActionFilter。您可以爲所有控制器設置全局過濾器或定義特定的每個操作。請參閱文檔中的Filters section。 ASP.NET Core也允許執行Model Validation

  • 在控制器操作執行期間,應儘快引發異常並停止進一步的管道執行。是的,可以在任何級別(動作級別,服務/業務層級,DA層級等)上引發異常。

如何處理引發的異常呢?