2017-08-31 72 views
1

我的項目,我使用的Web API與排序SOA architecture.In我想捕獲異常(由庫拋出),並返回HttpResposeMessage控制器之一。

我要的是應該有哪些繼承ApiController(class BaseController : ApiController)一BaseController和我的每個控制器應該由baseController
例如繼承class TaskController : BaseController如果有任何異常發生在我的控制器,那麼它應該被BaseController處理。 演示:
異常處理Web API控制器和投擲自定義錯誤消息

以下是我們與解決方案的項目(項目結構)

XYZ.Model 
XYZ.Repository 
XYZ.WebServices 
XYZ.Exception 
XYZ.UI 

代碼: XYZ.Model

public class Error 
{ 
    public string Code { get; set; } 
    public string Message { get; set; } 

} 

XYZ.Exception

// To create the custom exception as per our need 
public class BaseException : Exception 
{ 
    private Error _error; 
    public Error Error 
    { 
     get { return _error; } 
    } 

    public BaseException() 
    { 
     _error = new Error(); 
    } 

    public void SetErrorCode(string code) 
    { 
     _error.Code = code; 
    } 

    public void SetErrorMessage(string message) 
    { 
     _error.Message = message; 
    } 
} 


public class TaskNotFoundException : BaseException 
{ 
    public TaskNotFoundException() 
    { 
     string errorCode = "T0001"; 
     base.SetErrorCode(errorCode); 
     base.SetErrorMessage((new ExceptionMessage()).GetExceptionMessage(errorCode)); 
    } 
} 

XYZ.Repository

public Task UpdateTaskDetails(Task task) 
{ 
    try 
    { 
     //--Task updating logic--// 
    } 
    catch (Exception ex) 
    { 
     throw new TaskUpdateFailedException(); 
    } 
    return task; 
} 

XYZ.WebServices

public class BaseController : ApiController 
{ 
    public HttpResponseMessage CreateResponseMessage() 
    { 
     try 
     { 
      GetTasksByUserIdAndProjectId(new TaskQuery()); 
     } 
     catch(BaseException exception) 
     { 
      return Request.CreateResponse(HttpStatusCode.InternalServerError, exception.Error); 
     } 
    } 

    public virtual List<Task> GetTasksByUserIdAndProjectId(TaskQuery query) 
    { 
     Console.WriteLine("I can be overridden"); 
    } 
} 


public class TaskController : BaseController 
{ 
    [HttpPost] 
    public override List<Task> GetTasksByUserIdAndProjectId(TaskQuery query) 
    { 
     return _taskRepo.GetTasksByUserIdAndProjectId(query.UserId, query.ProjectId); 
    } 

} 

TaskController如果任何異常發生在GetTasksByUserIdAndProjectId方法應該拋出異常的BaseController CreateReponseMessage(),有它會返回HttpResponseMessage給客戶端。

注:每個控制器有多個GET /把/ Post方法,所以它不可能在BaseController所有方法(Web服務方法)聲明趕子類的例外在我的項目的當前結構。

有沒有更好的方式來處理的Web API異常,非常容易安裝在我的項目?

+0

這可以用一個異常過濾器可以做得更好。 – Nkosi

+0

@Nkosi,感謝您的建議,我已經實現了異常過濾器,並且工作正常。但是我還有一個問題:「我們可以在異常過濾器中處理一些驗證失敗錯誤類型嗎?AS驗證失敗並不是例外,但我希望它能在普通類中處理。」 – BhushanK

回答

3

我們使用一個異常過濾器是這樣的:

首先,我們創造我們自己的異常:

public class UserFriendlyException: Exception 
    { 
     public UserFriendlyException(string message) : base(message) { } 
     public UserFriendlyException(string message, Exception innerException) : base(message, innerException) { } 
    } 

然後我們創建一個過濾器:

public class UserFriendlyExceptionFilterAttribute: ExceptionFilterAttribute 
    { 
     public override void OnException(HttpActionExecutedContext context) 
     { 
      var friendlyException = context.Exception as UserFriendlyException; 
      if (friendlyException != null) 
      { 
       context.Response = context.Request.CreateResponse(HttpStatusCode.BadRequest, new {Message = friendlyException.Message}); 
      } 
     } 
    } 

終於在配置了的WebAPI我們添加該過濾器。

public static class WebApiConfig 
    { 
     public static void Register(HttpConfiguration config) 
     { 
      ... 


      config.Filters.Add(new UserFriendlyExceptionFilterAttribute()); 

      ... 
     } 
    } 

有了這個解決方案,您可以在代碼中隨處亂扔UserFriendlyException和響應將根據過濾器。

+0

感謝您的回答,我已經實現了異常過濾器並且工作正常。但是我還有一個問題:「我們可以在異常過濾器中處理一些驗證失敗錯誤類型的東西嗎?AS驗證失敗並不是例外,但我希望它能在普通類中處理。」 – BhushanK