基于 abp vNext 和 .NET Core 开发博客项目 - 异常处理和日志记录
1|0系列文章
- 基于 abp vNext 和 .NET Core 开发博客项目 - 使用 abp cli 搭建项目
- 基于 abp vNext 和 .NET Core 开发博客项目 - 给项目瘦身,让它跑起来
- 基于 abp vNext 和 .NET Core 开发博客项目 - 完善与美化,Swagger登场
- 基于 abp vNext 和 .NET Core 开发博客项目 - 数据访问和代码优先
- 基于 abp vNext 和 .NET Core 开发博客项目 - 自定义仓储之增删改查
- 基于 abp vNext 和 .NET Core 开发博客项目 - 统一规范API,包装返回模型
- 基于 abp vNext 和 .NET Core 开发博客项目 - 再说Swagger,分组、描述、小绿锁
- 基于 abp vNext 和 .NET Core 开发博客项目 - 接入GitHub,用JWT保护你的API
- 基于 abp vNext 和 .NET Core 开发博客项目 - 异常处理和日志记录
- 基于 abp vNext 和 .NET Core 开发博客项目 - 使用Redis缓存数据
- 基于 abp vNext 和 .NET Core 开发博客项目 - 集成Hangfire实现定时任务处理
- 基于 abp vNext 和 .NET Core 开发博客项目 - 用AutoMapper搞定对象映射
- 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(一)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(二)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 定时任务最佳实战(三)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(一)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(二)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(三)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(四)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 博客接口实战篇(五)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(一)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(二)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(三)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(四)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(五)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(六)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(七)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(八)
- 基于 abp vNext 和 .NET Core 开发博客项目 - Blazor 实战系列(九)
- 基于 abp vNext 和 .NET Core 开发博客项目 - 终结篇之发布项目
在开始之前,我们实现一个之前的遗留问题,这个问题是有人在GitHub Issues(https://github.com/Meowv/Blog/issues/8)上提出来的,就是当我们对Swagger进行分组,实现IDocumentFilter
接口添加了文档描述信息后,切换分组时会显示不属于当前分组的Tag。
经过研究和分析发现,是可以解决的,我不知道大家有没有更好的办法,我的实现方法请看:
根据调试代码发现,我们可以从context.ApiDescriptions
获取到当前显示的是哪一个分组下的API。
然后使用GetType().GetField(string name, BindingFlags bindingAttr)
获取到_source
,当前项目的所有API,里面同时也包含了ABP默认生成的一些接口。
再将API中不属于当前分组的API筛选掉,用Select查询出所有的Controller名称进行去重。
因为OpenApiTag
中的Name名称与Controller的Name是一致的,所以最后将包含controllers
名称的tag查询出来取反,即可满足需求。
上一篇文章(https://www.cnblogs.com/meowv/p/12935693.html)集成了GitHub,使用JWT的方式完成了身份认证和授权,保护了我们写的API接口。
本篇主要实现对项目中出现的异常仅需处理,当出现不可避免的错误时,或者未授权用户调用接口时,可以进行有效的监控和日志记录。
目前调用未授权接口,会直接返回一个状态码为401的错误页面,这样显得太不友好,我们还是用之前写的统一返回模型来告诉调用者,你是未授权的,调不了我的接口,上篇也有提到过,我们将用两种方式来解决。
方式一 :使用AddJwtBearer()
扩展方法下面的options.Events
事件机制。
在项目启动时,实例化了OnChallenge
,如果用户调用未授权,将请求的状态码赋值为200,并返回模型数据。
如图所示,可以看到已经成功返回了一段比较友好的JSON数据。
方式二 :使用中间件的方式。
我们注释掉上面的代码,在.HttpApi.Hosting
添加文件夹Middleware,新建一个中间件ExceptionHandlerMiddleware.cs
RequestDelegate
是一种请求委托类型,用来处理HTTP请求的函数,返回的是delegate
,实现异步的Invoke
方法。
这里我写了一个比较通用的方法,当出现异常时直接执行ExceptionHandlerAsync()
方法,当没有异常发生时,在finally
中判断当前请求状态,可能是200?404?401?等等,不管它是什么,反正不是200,获取到状态码枚举的Key值用来当作错误信息返回,最后也执行ExceptionHandlerAsync()
方法,返回我们自定义的模型。
写好了中间件,然后在OnApplicationInitialization(...)
中使用它。
同样可以达到效果,相比之下他还支持状态非401的错误返回,比如我们访问一个不存在的页面:https://localhost:44388/aaa ,也可以友好的进行处理。
当然这两种方式可以共存,互不影响。
还有一种处理异常的方式,就是我们的过滤器Filter,abp已经默认为我们实现了全局的异常模块,详情可以看其文档:https://docs.abp.io/zh-Hans/abp/latest/Exception-Handling ,在这里,我准备移除abp提供的异常处理模块,自己实现一个。
先看一下目前的异常显示情况,我们在HelloWorldController
中写一个异常接口。
按理说,他应该会执行到我们写的ExceptionHandlerMiddleware
中间件中去,但是被我们的Filter进行拦截了,现在我们移除默认的拦截器AbpExceptionFilter
还是在模块类MeowvBlogHttpApiHostingModule
,ConfigureServices()
方法中。
从options.Filters
中找到AbpExceptionFilter
,然后Remove掉,此时再看一下有异常的接口。
当我们注释掉我们的中间件时,他就会显示如下图这样。
这个页面有没有很熟悉的感觉?相信做过.net core开发的都遇到过吧。
ok,现在为止已经完美显示了。但到这里还远远不够,说好的自己实现Filter呢?我们现在实现Filter又有什么用呢?我们可以在Filter中可以做一些日志记录。
在.HttpApi.Hosting
层添加文件夹Filters,新建一个MeowvBlogExceptionFilter.cs
的Filter,他需要实现我们的IExceptionFilter
接口的OnExceptionAsync()
方法即可。
OnException(...)
方法很简单,这里只做了记录日志的操作,剩下的交给我们中间件去处理吧。
注意,一定要在移除默认AbpExceptionFilter
后,将我们自己实现的MeowvBlogExceptionFilter
在模块类ConfigureServices()
方法中注入到系统。
说到日志,就有很多种处理方式,请选择你熟悉的方式,我这里将使用log4net
进行处理,仅供参考。
在.ToolKits
层添加log4net
包,使用命令安装:Install-Package log4net
,然后添加文件夹Helper,新建一个LoggerHelper.cs
。
在.HttpApi.Hosting
中添加log4net配置文件,log4net.config
配置文件如下:
此时再去调用 .../HelloWorld/Exception,将会得到日志文件,内容是以JSON格式进行存储的。
关于Filter的更多用法可以参考微软官方文档:https://docs.microsoft.com/zh-cn/aspnet/core/mvc/controllers/filters
到这里,系统的异常处理和日志记录便完成了,你学会了吗?😁😁😁
开源地址:https://github.com/Meowv/Blog/tree/blog_tutorial
__EOF__

本文链接:https://www.cnblogs.com/meowv/p/12943699.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?