Web API 异常处理
Web Api的ExceptionFilter只能截获并处理Action执行过程中发生的异常,在Action执行过程之外如果出现异常,ExceptionFilter是无能为力的。
这些异常包括:
1、 Controller构造方法中出现的异常
2、 MessageHandlers中出现的异常
3、 路由过程中出现的异常
4、 Body在序列化/反序列化过程中出现的异常
由此可以看出,ExceptionFilter只能解决ApiControler成功实例化后并执行Action期间出现的异常;为了解决这一个问题,在WEB API中除了ExceptionFilter外还引入了两个针对异常记录、处理的扩展点:
IExceptionLogger 和IExceptionHandler。
而这两个扩展是作为Web API的管道组件进行注册管理的,并且,他们有不同的分工:
IExceptionLogger作为异常日志记录组件,负责异常发生后的日志记录,他贯穿于整个Web API的生命周期中,在Web API框架里,任何一个请求周期中出现任何一个未被捕获/处理的异常都会首先进入这个异常日志记录管道进行异常Log记录,在Web API中可以注册多个IExceptionLogger实例负责不同的异常处理。
IExceptionHandler作为异常处理组件,负责异常发生后的处理工作,他处于异常处理管道的最末端,当IExceptionLogger组件进行一场记录完毕、没有相关的ExceptoinFilter进行异常处理时,才会最终调用ExceptionHandler进行异常处理,在Web API中,有且仅有一个ExceptionHandler进行异常的处理。
在Web API框架中给出了两个基类:ExceptionLogger和ExceptionHandler,在使用ExceptionLogger基类时,他提供了ShouldLog虚方法,该方法在基类中被调用,其作用在于避免同一个异常被同一个ExceptionLogger实例重复记录(如当后续的管道中该异常又被抛出,或者同一个ExceptionLogger对象不小心被注册了两次就会出现重复记录的可能)我们也能复写ShouldLog方法加入我们自己的异常记录判断逻辑以针对不同的场景进行不同的ExceptionLogger调用。如果有兴趣可以反编译一下ExceptionLogger基类看看,他使用了显示接口实现,挺有意思的一个技巧。下面我们来看一个ExceptionLogger使用的例子:

public class ErroLogger : ExceptionLogger
{
public async Task LogAsync(ExceptionLoggerContext context, CancellationToken cancellationToken)
{
var sb = new StringBuilder();
//获取Log组件
ILogger log = LogManager.GetCurrentClassLogger(); var request = context.Request; sb.AppendLine("URL:");
//获取URL
var url = request.RequestUri.ToString();
sb.AppendLine(url); log.Error(context.Exception,sb.ToString(),"");
} public override bool ShouldLog(ExceptionLoggerContext context)
{
return context.Exception is DemoException && base.ShouldLog(context);
}
}

在这个例子中,我们重写了ShouldLog,保证了这个ExceptionLogger只记录DemoException这个类型的异常,并且也调用了基类方法,保证不会重复记录同一个异常。在LogAsync方法中,我通过Log组件记录了导致异常的请求URL,也记录了异常信息。
接下来我们要对这个组件进行注册:
在App_Start/WebApiConfig.cs文件中的Register方法中写入
config.Services.Add(typeof(IExceptionLogger),new ErroLogger());
这样,一个针对DemoException的异常记录组件就开发完成并注册完成了,当Web API执行管道中出现未处理的DemoException异常,均会调用则个组件进行记录。
接下来我们来写一个ExceptionHandler,在整个Web API框架中,ExceptionHandler只能提供一个实例,与ExceptionLogger一样,我们可以继承ExceptionHandler基类来简化异常处理,在ExceptionHandler中也提供了ShouldHandle方法来判断该异常是否应该处理,避免重复处理管道中其他环节重复抛出的异常。我们也同样提供一个例子:

public class ErrorHandler : ExceptionHandler
{
public override async Task HandleAsync(ExceptionHandlerContext context, CancellationToken cancellationToken)
{
if (context.Exception is DemoException)
{
context.Result = new ResponseMessageResult(context.Request.CreateResponse(HttpStatusCode.BadRequest,new {Message=context.Exception.Message}));
}
else
{
context.Result = new ResponseMessageResult(context.Request.CreateResponse(HttpStatusCode.InternalServerError,new {Message = "服务器已被外星人绑架"}));
}
}
}

在这个例子中,我们判断了异常的类型,并根据不同的异常返回客户端不同的响应内容和不同的HTTP状态码。
然后在配置中注册这个异常处理模块,在App_Start/WebApiConfig.cs文件中的Register方法中写入
config.Services.Replace(typeof(IExceptionHandler),new ErrorHandler());
这样就替换了系统默认的ExceptionHandler,可以使用我们自定义的Handler进行异常的处理了。
在异常记录、处理过程中,我们都碰到相应的异常上下文参数,我们能通过这个参数获取当前请求的上下文,获取请求、响应(小心有时会为空哦)、捕获到该异常的catch块信息等内容,我们可以利用这些信息更好地描述、记录、处理异常。
到这里ExceptionLogger组件和ExceptionHandler组件简单的开发就完成了。在开发的过程中我们可以看到,ExceptionLogger负责了全局的异常记录,在Web API框架管道下出现未处理的异常ExceptionLogger都会进行捕获、记录。而ExceptionHandler和ExceptionFilter功能是有重叠的,那何时使用ExceptionHandler何时使用ExceptionFilter呢?我们可以将两者的区别列出如下的表格:
|
ExceptionFilter |
ExceptionHandler |
|
|
作用域 |
Controller、Action |
全局 |
|
实例个数 |
无限制 |
全局唯一 |
|
作用条件 |
Controller实例化成功之后 |
Web API成功加载之后 |
经过上面的表我们可以看出,如果处理颗粒度细致到Controller、Action级别时,ExceptionFilter处理起来会更得心应手,他已经能精确定位到某个Action,然后可以针对当前Action做定制开发。而ExceptionHandler作用域远大于ExceptionFilter,他处理全局更有优势。
Web API 异常处理的更多相关文章
- Asp.Net Web API 2第七课——Web API异常处理
前言 阅读本文之前,您也可以到Asp.Net Web API 2 系列导航进行查看 http://www.cnblogs.com/aehyok/p/3446289.html 本文主要来讲解Asp.Ne ...
- WEB API异常处理
当一个web api抛出一个异常后 此异常会被转化成一个HTTP响应 错误代码为500的服务错误 但是如果你不想让客户端看到500的错误码 你也可以自定义错误码 如下代码当用户输入的ID没有与之相关的 ...
- ASP.NET mvc4 WEB API异常处理
当一个web api抛出一个异常后 此异常会被转化成一个HTTP响应 错误代码为500的服务错误 但是如果你不想让客户端看到500的错误码 你也可以自定义错误码 如下代码当用户输入的ID没有与之相关的 ...
- ASP.NET Web API 异常处理 HttpResponseException 以及Angularjs获取异常信息并提示
一.HttpResponseException 如果一个Web API控制器抛出一个未捕捉异常,默认地,大多数异常都会被转化成一个带有状态码“500 – 内部服务器错误”的HTTP响应.HttpRes ...
- Web API系列(三) 异常处理
在上一篇教程中我为大家介绍了Web API中Filter的开发使用,其中讲到ExceptionFilter时留了一个坑:ExceptionFilter只能截获并处理Action执行过程中发生的异常,在 ...
- ASP.NET Web API系列教程目录
ASP.NET Web API系列教程目录 Introduction:What's This New Web API?引子:新的Web API是什么? Chapter 1: Getting Start ...
- Web API 2
Asp.Net Web API 2 官网菜鸟学习系列导航[持续更新中] 前言 本来一直参见于微软官网进行学习的, 官网网址http://www.asp.net/web-api.出于自己想锻炼一下学 ...
- ASP.NET Web API系列教程(目录)(转)
注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP.NET Web API.这是一个用来在.NET平台上建立HTTP服务的Web API框架,是微软的又一项令人振奋的技术.目前,国内 ...
- [转]ASP.NET Web API系列教程(目录)
本文转自:http://www.cnblogs.com/r01cn/archive/2012/11/11/2765432.html 注:微软随ASP.NET MVC 4一起还发布了一个框架,叫做ASP ...
随机推荐
- C - Rikka with Badminton --- HDU 6425 快速幂加组合数学
---恢复内容开始--- 题目链接: https://vjudge.net/problem/1812693/origin 这题的mod运算很恶心,真的... 本题有正反两个思路,一个是正面求解其不能成 ...
- ENQUIRE the predecessor to the World Wide Web.
看Building Responsive Data Visualization for the Web时介绍到了Enquire,表示wiki类系统实现了它的核心思想. 有点好奇是如何实现的,所以大概看 ...
- JavaScript基础笔记(二)变量、作用域和内存问题
变量.作用域和内存问题 一.基本类型和引用类型的值 基本类型值:简单的数据段 引用类型值:由多个值构成的对象 基本类型是按值访问的,引用类型是按引用访问的. 不能给基本类型的值添加属性,尽管不会报错. ...
- BUG——Celery ValueError: not enough values to unpack
背景 最近因项目需要,学习任务队列Celery的用法,跟着官网写Demo,出现如题错误,最终在github的Issues里找到解决办法,记录如下. 场景还原 本地环境如下: Windows 7 Pyt ...
- Ubuntu16.04搜狗输入法无法输入中文
搜狗输入法图标显示正常,但是无法输入中文,切换为中文输入时无待选中文,只能输入英文. 这种情况应该是搜狗输入法的配置出现了问题,因为重装输入法时配置文件夹会保留,因此重装无法解决问题. 解决方案: 1 ...
- Java泛型之Type体系
Type是java类型信息体系中的顶级接口,其中Class就是Type的一个直接实现类.此外,Type还有有四个直接子接口:ParameterizedType,TypeVariable,Wildcar ...
- db2 reorg详解
reorgchk,检查table index 是否需要重组.reorg 重组,重新放置数据位置.runstats 统计信息,可以优化查询器 一个完整的日常维护规范可以帮助 DBA 理顺每天需要的操作, ...
- Linux之磁盘分区篇
作业三: 1) 开启Linux系统前添加一块大小为20G的SCSI硬盘 2) 开启系统,右击桌面,打开终端 3) 为新加的硬盘分区,一个主分区大小为10G,剩余空间给扩展分区,在扩展分区上 ...
- 对Android中的堆栈的理解(Stack)
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/Ln_ZooFa/article/details/50337529 堆栈空间分配 栈(操作系统): ...
- Translate Angular >=4 with ngx-translate and multiple modules
原文:https://medium.com/@lopesgon/translate-angular-4-with-ngx-translate-and-multiple-modules-7d9f0252 ...