Asp.NetCore依赖注入和管道方式的异常处理及日志记录
前言
在业务系统,异常处理是所有开发人员必须面对的问题,在一定程度上,异常处理的能力反映出开发者对业务的驾驭水平;本章将着重介绍如何在 WebApi 程序中对异常进行捕获,然后利用 Nlog 组件进行记录;同时,还将介绍两种不同的
异常捕获方式:管道捕获/服务过滤;通过本练习,将学习到如何捕获异常、处理异常跳转、记录异常信息。
搭建框架
首先,创建一个 WebApi 项目,选择 Asp.Net Core Web 应用程序;
进一步选择 Api 模板,这里使用的 .netcore 版本为 2.1
取消勾选 “启用 Docker 支持(E)” 和 “为 Https 配置(C)”,点击确定,得到一个完整的 WebApi 项目框架,如图
直接按 F5 运行项目,一切正常,程序启动后进入默认路由调用,并输出结果
异常路由
一切看起来都非常正常和美好,但,祸之福所倚;接下来我们在 接口 Get() 中人为的制造一点麻烦。
[HttpGet] public ActionResult<IEnumerable<string>> Get(){ throw new Exception("出错了....."); return new string[] { "value1", "value2" };}
这是由于项目配置了运行环境变量 ASPNETCORE_ENVIRONMENT=Development 后,Startup.cs 中配置了开发环境下,使用系统默认页,所以我们才可以看到上面的异常信息
如果你把环境变量设置为 ASPNETCORE_ENVIRONMENT=Production ,你会发现,在异常发生的时候,你得到了一个空白页。
异常处理方式一:服务过滤
在传统的 Asp.Net MVC 应用程序中,我们一般都使用服务过滤的方式去捕获和处理异常,这种方式非常常见,而且可用性来说,体验也不错,幸运的是 Asp.Net Core 也完整的支持该方式,接下来创建一个全局异常处理类 CustomerExceptionFilter
CustomerExceptionFilter 继承自 IExceptionFilter 接口,并实现 void OnException(ExceptionContext context) 方法,在 CustomerExceptionFilter
构造方法中,定义了两个参数,用于记录异常日志和获取程序运行环境变量
在接下来的 OnException 方法中,利用 environment 进行产品环境的判断,并使用 logger 将日志写入硬盘文件中,为了将日志写入硬盘,
需要引用 Nuget 包 NLog.Extensions.Logging/NLog.Web.AspNetCore ,并在 Startup.cs 文件的 Configure 方法中添加扩展
上面的代码读取了配置文件 nlog.config 并设置为 NLog 的配置,该文件定义如下
<?xml version="1.0" encoding="utf-8" ?>
<nlog xmlns="http://www.nlog-project.org/schemas/NLog.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" autoReload="true" internalLogLevel="info">
<!-- Load the ASP.NET Core plugin -->
<extensions>
<add assembly="NLog.Web.AspNetCore"/>
</extensions>
<!-- Layout: https://github.com/NLog/NLog/wiki/Layout%20Renderers -->
<targets>
<target xsi:type="File" name="errorfile" fileName="/data/logs/logfilter/error-${shortdate}.log" layout="${longdate}|${logger}|${uppercase:${level}}| ${message} ${exception}|${aspnet-Request-Url}" />
<target xsi:type="Null" name="blackhole" />
</targets>
<rules>
<logger name="Microsoft.*" minlevel="Error" writeTo="blackhole" final="true" />
<logger name="*" minlevel="Error" writeTo="errorfile" />
</rules>
</nlog>
为了在 WebApi 控制器中使用 CustomerExceptionFilter 过滤器,我们还需要在 Startup.cs 将 CustomerExceptionFilter 注入到容器中
最后,在控制器 ValuesController 中应用该异常过滤器
现在,按 F5 启动程序,如预期所料,报错信息被 CustomerExceptionFilter 捕获,并转换为 json 格式输出
同时,NLog 组件也将日志信息记录到了硬盘中
异常处理方式二:中间件捕获
接下来利用 .NetCore 的管道模式,在中间件中对异常进行捕获,首先,创建一个中间件
代码比较简单,在管道中使用 try/catch 进行捕获异常,创建 HandleException(HttpContext context, Exception e) 处理异常,判断是 Development 环境下,输出详细的错误信息,非 Development 环境仅提示调用者“抱歉,出错了”,同时使用 NLog 组件将日志写入硬盘;
同样,在 Startup.cs 中将 ExceptionMiddleware 加入管道中一切就绪,按 F5 运行程序,网页中输出了期望中的 json 格式错误信息,同时 NLog 组件也将日志写入了硬盘
结语
在本例中,通过依赖注入和管道中间件的方式,演示了两种不同的全局捕获异常处理的过程;值得注意到是,两种方式对于 NLog 的使用,都是一样的,没有任何差别,代码无需改动;实际项目中,也是应当区分不同的业务场景,输出不同的
日志信息,不管是从安全或者是用户体验友好性上面来说,都是非常值得推荐的方式,全局异常捕获处理,完全和业务剥离。
努力为开源社区作贡献,推荐一个自己开发的基于 .netcore+pgsql 的快速开发脚手架,内置 ORM框架,github地址:https://github.com/lianggx/mystaging
文中如有疏漏之处,欢迎指正。
源码下载:https://files.cnblogs.com/files/viter/Ron.LogFilter.zip
Asp.NetCore依赖注入和管道方式的异常处理及日志记录相关推荐
- Spring依赖注入(注解方式)
Spring依赖注入(注解方式) 在Spring中,尽管使用XML配置文件就可以实现Bean的装配工作,但如果应用中Bean的数量较多,会导致XML配置文件过于臃肿,从而给程序的维护与升级带来一定的困 ...
- Spring学习3 - Bean的属性、DI依赖注入三种方式
文章目录 1. 属性设置 - XML配置文件.以及与其等价的注解形式 2. 依赖注入DI的方式 2.1 属性自动注入 - 不推荐 代码准备阶段 代码测试 2.2 子节点构造器注入 - 不推荐 2.3 ...
- ASP.NET Core 异常处理与日志记录
ASP.NET Core 异常处理与日志记录 参考文章: (1)ASP.NET Core 异常处理与日志记录 (2)https://www.cnblogs.com/vipyoumay/p/783806 ...
- .NETCore——依赖注入
本文章是我听B站杨中科的所做的笔记 杨中科B站视频链接:.NET 6教程,.Net Core 2022视频教程,杨中科主讲_哔哩哔哩_bilibili 1.概念 生活中的"控制反转" ...
- Spring第七弹—依赖注入之注解方式注入及编码解析@Resource原理
注入依赖对象可以采用手工装配或自动装配,在实际应用中建议使用手工装配,因为自动装配会产生未知情况,开发人员无法预见最终的装配结果. 手工装配依赖对象 手工装配依赖对象,在这种方式中又有两种编 ...
- spring的依赖注入 -------基于注解方式
前言: 做了2年的软件,刚开始入行的时候,没有个目标基本上都是在摸索,技术看的我眼花缭乱,这个想学,那个也想学结果是对很多技术一知半解的,工作中才发现,我们要掌握的一门可以搞定快速开发搞定所有业务需求 ...
- spring依赖注入三种方式
首先,要学习Spring中的Bean的注入方式,就要先了解什么是依赖注入. 依赖注入是指:让调用类对某一接口的实现类的依赖关系由第三方注入,以此来消除调用类对某一接口实现类的依赖. Spring容器中 ...
- 22 springboot依赖注入三种方式
1 基于构造函数的依赖注入 Spring 基于构造函数的依赖注入_w3cschoolJ虽然当前有关Spring Framework(5.0.3)的文档仅定义了两种主要的注入类型,但实际上有三种 pub ...
- Spring 依赖注入三种方式的实现,及循环依赖问题的解决(源码+XML配置)
搬砖啦,搬砖啦,这几天在看Spring相关的书,下面给大家分享一下这几天的心得与收获,Go Go Go! Spring支持两种依赖注入方式,分别是属性注入,构造函数注入.除此之外,Spring还支持工 ...
最新文章
- IT 往事录:苹果 Mac 之父,却在 Mac 问世前黯然退场
- NetDevOps — SNMP 协议
- 模拟浏览器自动化测试工具Selenium之六设置代理篇
- c语言return 11,二级C语言教程章节测试11.对函数的进一步讨论
- 解决Xcode升级,导致以前安装的插件失效的办法
- 网页设计中 透明效果的使用技巧
- Flex4.5中检测网络连接类型
- python tkinter背景图片_如何在tkinter中有背景图像和按钮?
- [vscode] markdown_index----可以为你的markdown标题添加序号的插件
- python申明变量和赋值_Python入门(二)
- C# 自定义控件基础知识
- STAMP:Short-TermAttention/MemoryPriorityModelfor Session-basedRecommendation
- 超声成像Matlab源码
- JZOJ5465. 【NOIP2017提高A组冲刺11.9】道路重建
- 提升测试效率都有哪些具体手段?
- 鼠标放在可以点击的文字上,变成小手样式
- QQ无法访问个人文件夹,QQ,wx等程序无法正常启动
- 电脑游戏业编年史之一游戏的诞生
- linkis Invalid bound statement (not found): com.webank.wedatasphere.linkis.metadata.hive.dao.HiveMet
- 修复登录接口版影视微信小程序全新UI程序源码下载附带简单教程