这里我写了一个比较通用的方法,当出现异常时直接执行ExceptionHandlerAsync()方法,当没有异常发生时,在finally中判断当前请求状态,可能是200?404?401?等等,不管它是什么,反正不是200,获取到状态码枚举的Key值用来当作错误信息返回,最后也执行ExceptionHandlerAsync()方法,返回我们自定义的模型。
写好了中间件,然后在OnApplicationInitialization(...)中使用它。
public override void OnApplicationInitialization(ApplicationInitializationContext context) { ... // 异常处理中间件 app.UseMiddleware<ExceptionHandlerMiddleware>(); ... }同样可以达到效果,相比之下他还支持状态非401的错误返回,比如我们访问一个不存在的页面:https://localhost:44388/aaa ,也可以友好的进行处理。
当然这两种方式可以共存,互不影响。
还有一种处理异常的方式,就是我们的过滤器Filter,abp已经默认为我们实现了全局的异常模块,详情可以看其文档:https://docs.abp.io/zh-Hans/abp/latest/Exception-Handling ,在这里,我准备移除abp提供的异常处理模块,自己实现一个。
先看一下目前的异常显示情况,我们在HelloWorldController中写一个异常接口。
//HelloWorldController.cs ... [HttpGet] [Route("Exception")] public string Exception() { throw new NotImplementedException("这是一个未实现的异常接口"); } ...按理说,他应该会执行到我们写的ExceptionHandlerMiddleware中间件中去,但是被我们的Filter进行拦截了,现在我们移除默认的拦截器AbpExceptionFilter
还是在模块类MeowvBlogHttpApiHostingModule,ConfigureServices()方法中。
Configure<MvcOptions>(options => { var filterMetadata = options.Filters.FirstOrDefault(x => x is ServiceFilterAttribute attribute && attribute.ServiceType.Equals(typeof(AbpExceptionFilter))); // 移除 AbpExceptionFilter options.Filters.Remove(filterMetadata); });从options.Filters中找到AbpExceptionFilter,然后Remove掉,此时再看一下有异常的接口。
当我们注释掉我们的中间件时,他就会显示如下图这样。
这个页面有没有很熟悉的感觉?相信做过.net core开发的都遇到过吧。
ok,现在为止已经完美显示了。但到这里还远远不够,说好的自己实现Filter呢?我们现在实现Filter又有什么用呢?我们可以在Filter中可以做一些日志记录。
在.HttpApi.Hosting层添加文件夹Filters,新建一个MeowvBlogExceptionFilter.cs的Filter,他需要实现我们的IExceptionFilter接口的OnExceptionAsync()方法即可。
//MeowvBlogExceptionFilter.cs using Meowv.Blog.ToolKits.Helper; using Microsoft.AspNetCore.Mvc.Filters; namespace Meowv.Blog.HttpApi.Hosting.Filters { public class MeowvBlogExceptionFilter : IExceptionFilter { /// <summary> /// 异常处理 /// </summary> /// <param></param> /// <returns></returns> public void OnException(ExceptionContext context) { // 日志记录 LoggerHelper.WriteToFile($"{context.HttpContext.Request.Path}|{context.Exception.Message}", context.Exception); } } }OnException(...)方法很简单,这里只做了记录日志的操作,剩下的交给我们中间件去处理吧。
注意,一定要在移除默认AbpExceptionFilter后,将我们自己实现的MeowvBlogExceptionFilter在模块类ConfigureServices()方法中注入到系统。
... Configure<MvcOptions>(options => { ... // 添加自己实现的 MeowvBlogExceptionFilter options.Filters.Add(typeof(MeowvBlogExceptionFilter)); }); ...说到日志,就有很多种处理方式,请选择你熟悉的方式,我这里将使用log4net进行处理,仅供参考。