2016-02-09 46 views
1

我有很多的控制器方法的WebAPI類似於以下:重構錯誤處理中的WebAPI控制器

public IHttpActionResult Delete(int id) 
{ 
    var command = new DeleteItemCommand() { Id = id }; 

    try 
    { 
     _deleteCommandHandler.Handle(command); 
    } 
    catch (CommandHandlerResourceNotFoundException) 
    { 
     throw new HttpResponseException(HttpStatusCode.NotFound); 
    } 
    catch(CommandHandlerException) 
    { 
     throw new HttpResponseException(HttpStatusCode.InternalServerError); 
    } 
    // More catches etc... 

    return Ok(); 
} 

命令處理程序(在此實例中_deleteCommandHandler)早在執行注射的命令可以是內置在該方法中或使用WebApi的自動方法。

我想什麼做的是封裝的try/catch錯誤處理在一個私人的方法,並最終以類似控制器:

public IHttpActionResult Delete(int id) 
{ 
    var command = new DeleteItemCommand() { Id = id }; 

    return ExecuteCommand(x => _deleteCommandHandler.Handle(command)); 
} 

我不知道什麼是私人的簽名應該是ExecuteCommand方法。

回答

1

我認爲你可以在這樣的方法Invoke你的行動:

public IHttpActionResult Delete(int id) 
{ 
    return ExecuteCommand(() => { 
     var command = new DeleteItemCommand() { Id = id }; 
     _deleteCommandHandler.Handle(command); 
    }); 
} 

private IHttpActionResult ExecuteCommand(Action action) 
{ 
    try 
    { 
     action.Invoke(); 
     //or: action(); 
    } 
    catch (CommandHandlerResourceNotFoundException) 
    { 
     return HttpResponseException(HttpStatusCode.NotFound); 
    } 
    catch (CommandHandlerException) 
    { 
     return HttpResponseException(HttpStatusCode.InternalServerError); 
    } 
    return Ok(); 
} 

HttpResponseException一個很好的參考。

0

我會創建一個自定義錯誤處理程序過濾器,並以集中形式處理所有可能的錯誤。通過這種方式,您可以拋出操作方法中的任何異常,然後將它們捕獲到篩選器中,從而可以處理它們並相應地更改響應。

public class NotImplExceptionFilterAttribute : ExceptionFilterAttribute 
{ 
    public override void OnException(HttpActionExecutedContext context) 
    { 
     if (context.Exception is NotImplementedException) 
     { 
      context.Response = new HttpResponseMessage(HttpStatusCode.NotImplemented); 
     } 
    } 
} 

該示例摘自this article,您可以在其中找到更詳細的概念。

0

下面是類似shA.t的答案的解決方案,但例外是在字典映射和try/catch語句的邏輯是一個擴展方法:

public class TestController:ApiController 
    { 
     public IHttpActionResult Delete(int id) 
     { 
      return ExecuteCommand(() => { 
       var command = new DeleteItemCommand() { Id = id }; 
       _deleteCommandHandler.Handle(command); 
      }); 
    } 

    private IHttpActionResult ExecuteCommand(Action action) 
    { 
     return action.SafeInvoke(); 
    } 
} 

public static class ActionExtensions 
{ 
    private static readonly Dictionary<Type, HttpStatusCode> _exceptionToStatusCodeLookup = new Dictionary<Type, HttpStatusCode> 
    { 
     {typeof(CommandHandlerResourceNotFoundException), HttpStatusCode.NotFound }, 
     {typeof(CommandHandlerException), HttpStatusCode.InternalServerError }, 
    }; 

    public static IHttpActionResult SafeInvoke(this Action action) 
    { 
     try 
     { 
      action(); 
     } 
     catch (Exception ex) 
     { 
      var statusCode = _exceptionToStatusCodeLookup.ContainsKey(ex.GetType()) ? _exceptionToStatusCodeLookup[ex.GetType()] : HttpStatusCode.InternalServerError; 
      return new HttpResponseException(statusCode); 
     } 

     return new OkResult(); 
    } 
}