异常处理Web API控制器和投掷自定义错误消息

问题描述:

我的项目,我使用的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

我们使用一个异常过滤器是这样的:

首先,我们创造我们自己的异常:

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