Web API 控制器中的异常处理并抛出自定义错误消息
Exception handling in Web API Controller and throwing custom error message
对于我的一个项目,我正在使用 Web API 和某种 SOA architecture.In 控制器我想捕获异常(由存储库抛出)和 return HttpResposeMessage
.
我想要的是应该有一个继承 ApiController (class BaseController : ApiController
) 的 BaseController,并且我的每个控制器都应该由 baseController
继承,例如class TaskController : BaseController
如果我的控制器发生任何异常,则应由 BaseController
处理。
演示:
以下是我们 VS 解决方案中的项目:(项目结构)
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()
,然后return和HttpResponseMessage
客户。
注意:在每个Controller中有多个Get/Put/Post方法,所以不可能在BaseController
中声明所有方法(web服务方法)来捕获当前结构中子class的异常我的项目。
有没有更好的方法来处理 Web API 中的异常,并且很容易适合我的项目?
我们使用这样的异常过滤器:
首先我们创建自己的异常:
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,响应将根据过滤器进行。
对于我的一个项目,我正在使用 Web API 和某种 SOA architecture.In 控制器我想捕获异常(由存储库抛出)和 return HttpResposeMessage
.
我想要的是应该有一个继承 ApiController (class BaseController : ApiController
) 的 BaseController,并且我的每个控制器都应该由 baseController
继承,例如class TaskController : BaseController
如果我的控制器发生任何异常,则应由 BaseController
处理。
演示:
以下是我们 VS 解决方案中的项目:(项目结构)
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()
,然后return和HttpResponseMessage
客户。
注意:在每个Controller中有多个Get/Put/Post方法,所以不可能在BaseController
中声明所有方法(web服务方法)来捕获当前结构中子class的异常我的项目。
有没有更好的方法来处理 Web API 中的异常,并且很容易适合我的项目?
我们使用这样的异常过滤器:
首先我们创建自己的异常:
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,响应将根据过滤器进行。