前几天在webapi项目中遇到一个问题:Controller构造函数中抛出异常时全局过滤器捕获不到,于是网搜一把写下这篇博客作为总结。
HttpResponseException
通常在WebAPI的Controller中抛出的未处理异常,会以500的形式返回到客户端。而
HttpResponseException
会返回我们指定的状态码,如返回501:
public HttpResponseMessage Exception()
{
//直接在Action中抛出HttpResponseException类型异常
throw new HttpResponseException(HttpStatusCode.NotImplemented);
}
在抛出
HttpResponseException
时,可将
HttpResponseMessage类型的实例作为参数以提供给客户端更多的信息。
HttpError
public HttpResponseMessage Exception()
{
//使用Request对象创建返回到客户端的错误信息
Request.CreateErrorResponse()
}
CreateErrorResponse
方法是
HttpResponseMessage
类型的可扩展方法,该方法最终会调用扩展方法
CreateResponse
返回一个
HttpResponseMessage
类型的对象(ASP.NET WebAPI中Action的返回值最终都会被转换为HttpResponseMessage类型的对象),该对象包含一个
HttpError
类型实例。
Exception Filters
自定义派生自
ExceptionFilterAttribute或
IExceptionFilter的异常处理类用于异常的处理。
过滤器可分为三个级别:
- Action
- Controller
- Global
注意:ASP.NET MVC和ASP.NET WebAPI的异常过滤器不可混用
ExceptionHandler
以下情形中的异常,过滤器是无法捕获到的:
- Controller构造函数中抛出的异常
- 消息处理器 中抛出的异常
- 路由过程中出现的异常
- 其它过滤器中抛出的异常
- 序列化返回内容时抛出的异常
解决方案如下:
自定义异常处理器,两种方式
- 实现接口 IExceptionHandler
- 继承
public class XfhExceptionHandler : ExceptionHandler
{
public override void Handle(ExceptionHandlerContext context)
{
context.Result = new ResponseMessageResult(
context.Request.CreateErrorResponse(HttpStatusCode.BadRequest, "发生了不可描述的错误!")
);
//new InternalServerErrorResult(context.Request);
}
}
替换ASP.NET WebAPI默认的异常处理器
public static void Register(HttpConfiguration config)
{
config.Services.Replace(typeof(IExceptionHandler), new XfhExceptionHandler());
}
PS:若要记录未处理异常日志可实现接口
IExceptionLogger或继承
ExceptionLogger小结
IExceptionFilter只能处理Action中发生的未处理异常,IExceptionHandler可以处理任何地方发生的未处理异常。
相关阅读
catch all unhandled exceptions in ASP.NET Web Api Handling Errors in Web API Using Exception Filters and Exception Handlers Exception Handling in ASP.NET Web API Global Error Handling in ASP.NET Web API 2 Action Results in Web API 2版权声明
本文为作者原创,版权归作者
雪飞鸿所有。 转载必须保留文章的完整性,且在页面明显位置处标明
原文链接。
如有问题, 请
发送邮件和作者联系。