这些异常包孕:
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.WordStr(typeof(IExceptionHandler),new ErrorHandler());
这样就替换了系统默认的ExceptionHandler,可以使用我们自界说的Handler进行异常的措置惩罚惩罚了。