这些非常包含:
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 非常处置惩罚经验总结的细致内容,更多请关注ki4网别的相干文章!