ASP.NET Web API 2中的错误处理

前几天在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

自定义派生自ExceptionFilterAttributeIExceptionFilter的异常处理类用于异常的处理。

过滤器可分为三个级别:

  • Action
  • Controller
  • Global

注意:ASP.NET MVC和ASP.NET WebAPI的异常过滤器不可混用

ExceptionHandler

以下情形中的异常,过滤器是无法捕获到的:

  • Controller构造函数中抛出的异常
  • 消息处理器中抛出的异常
  • 路由过程中出现的异常
  • 其它过滤器中抛出的异常
  • 序列化返回内容时抛出的异常

解决方案如下: 自定义异常处理器,两种方式

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

版权声明

本文为作者原创,版权归作者雪飞鸿所有。 转载必须保留文章的完整性,且在页面明显位置处标明原文链接

如有问题, 请发送邮件和作者联系。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏木子昭的博客

<数据库>高性能Redis快速入门 | (附Redis常用命令)Redis存储数据 的 五种数据结构

Redis是一个非关系型数据库,也是一个内存数据库(确切一点,可以把它看做内存数据结构服务器, 设计极其精简,如果说在mongo里面还能看到表的影子"集合(c...

4009
来自专栏拂晓风起

中文URL编码

1775
来自专栏技术记录

通讯协议序列化解读(一) Protobuf详解教程

4747
来自专栏闵开慧

java获取cpu、内存、硬盘信息

1 下载安装sigar-1.6.4.zip     使用java自带的包获取系统数据,容易找不到包,尤其是内存信息不够准确,所以选择使用sigar获取系统信息。...

7729
来自专栏DOTNET

【翻译】MongoDB指南/引言

【原文地址】https://docs.mongodb.com/manual/ 引言 MongoDB是一种开源文档型数据库,它具有高性能,高可用性,自动扩展性 1...

2596
来自专栏大内老A

总体介绍ASP.NET Web API下Controller的激活与释放流程

通过《ASP.NET Web API的Controller是如何被创建的?》我们已经对HttpController激活系统的核心对象有了深刻的了解,这些对象包括...

1947
来自专栏武培轩的专栏

Runtime源码解析(JDK1.8)

package java.lang; import sun.reflect.CallerSensitive; import sun.reflect.Refle...

3629
来自专栏老马说编程

(87) 类加载机制 / 计算机程序的思维逻辑

上节,我们探讨了动态代理,在前几节中,我们多次提到了类加载器ClassLoader,本节就来详细讨论Java中的类加载机制与ClassLoader。 类加载...

1998
来自专栏用户2442861的专栏

Java IO学习笔记(一):File类

http://www.cnblogs.com/lich/archive/2011/12/10/2283445.html

691
来自专栏北京马哥教育

Python实现线程安全队列

作者:愤怒的屎壳螂 来源:http://blog.csdn.net/hit0803107/article/details/52876143 最近学习spa...

4427

扫码关注云+社区

领取腾讯云代金券