Asp.NetCore依赖注入和管道方式的异常处理及日志记录

前言

    在业务系统,异常处理是所有开发人员必须面对的问题,在一定程度上,异常处理的能力反映出开发者对业务的驾驭水平;本章将着重介绍如何在 WebApi 程序中对异常进行捕获,然后利用 Nlog 组件进行记录;同时,还将介绍两种不同的
异常捕获方式:管道捕获/服务过滤;通过本练习,将学习到如何捕获异常、处理异常跳转、记录异常信息。

搭建框架

    首先,创建一个 WebApi 项目,选择 Asp.Net Core Web 应用程序;

640?wx_fmt=png

  • 进一步选择 Api 模板,这里使用的 .netcore 版本为 2.1

640?wx_fmt=png

  • 取消勾选 “启用 Docker 支持(E)” 和 “为 Https 配置(C)”,点击确定,得到一个完整的 WebApi 项目框架,如图

640?wx_fmt=png

  • 直接按 F5 运行项目,一切正常,程序启动后进入默认路由调用,并输出结果

异常路由

640?wx_fmt=jpeg

  • 一切看起来都非常正常和美好,但,祸之福所倚;接下来我们在 接口 Get() 中人为的制造一点麻烦。

        [HttpGet]        public ActionResult<IEnumerable<string>> Get(){            throw new Exception("出错了.....");            return new string[] { "value1", "value2" };}
  • 这是由于项目配置了运行环境变量 ASPNETCORE_ENVIRONMENT=Development 后,Startup.cs 中配置了开发环境下,使用系统默认页,所以我们才可以看到上面的异常信息

640?wx_fmt=png

  • 如果你把环境变量设置为 ASPNETCORE_ENVIRONMENT=Production ,你会发现,在异常发生的时候,你得到了一个空白页。

640?wx_fmt=png

异常处理方式一:服务过滤

    在传统的 Asp.Net MVC 应用程序中,我们一般都使用服务过滤的方式去捕获和处理异常,这种方式非常常见,而且可用性来说,体验也不错,幸运的是 Asp.Net Core 也完整的支持该方式,接下来创建一个全局异常处理类 CustomerExceptionFilter


  • CustomerExceptionFilter 继承自 IExceptionFilter 接口,并实现 void OnException(ExceptionContext context) 方法,在 CustomerExceptionFilter
    构造方法中,定义了两个参数,用于记录异常日志和获取程序运行环境变量

640?wx_fmt=png

  • 在接下来的 OnException 方法中,利用 environment 进行产品环境的判断,并使用 logger 将日志写入硬盘文件中,为了将日志写入硬盘,
    需要引用 Nuget 包 NLog.Extensions.Logging/NLog.Web.AspNetCore ,并在 Startup.cs 文件的 Configure 方法中添加扩展

640?wx_fmt=png

  • 上面的代码读取了配置文件 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 注入到容器中

640?wx_fmt=png

  • 最后,在控制器 ValuesController 中应用该异常过滤器

640?wx_fmt=png

  • 现在,按 F5 启动程序,如预期所料,报错信息被 CustomerExceptionFilter 捕获,并转换为 json 格式输出

640?wx_fmt=png

  • 同时,NLog 组件也将日志信息记录到了硬盘中

640?wx_fmt=png

异常处理方式二:中间件捕获

    接下来利用 .NetCore 的管道模式,在中间件中对异常进行捕获,首先,创建一个中间件

  • 代码比较简单,在管道中使用 try/catch 进行捕获异常,创建 HandleException(HttpContext context, Exception e) 处理异常,判断是 Development 环境下,输出详细的错误信息,非 Development 环境仅提示调用者“抱歉,出错了”,同时使用 NLog 组件将日志写入硬盘;
    同样,在 Startup.cs 中将 ExceptionMiddleware 加入管道中

  • 一切就绪,按 F5 运行程序,网页中输出了期望中的 json 格式错误信息,同时 NLog 组件也将日志写入了硬盘

640?wx_fmt=png

结语

    在本例中,通过依赖注入和管道中间件的方式,演示了两种不同的全局捕获异常处理的过程;值得注意到是,两种方式对于 NLog 的使用,都是一样的,没有任何差别,代码无需改动;实际项目中,也是应当区分不同的业务场景,输出不同的
日志信息,不管是从安全或者是用户体验友好性上面来说,都是非常值得推荐的方式,全局异常捕获处理,完全和业务剥离。

  • 努力为开源社区作贡献,推荐一个自己开发的基于 .netcore+pgsql 的快速开发脚手架,内置 ORM框架,github地址:https://github.com/lianggx/mystaging

  • 文中如有疏漏之处,欢迎指正。

  • 源码下载:https://files.cnblogs.com/files/viter/Ron.LogFilter.zip


本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/318840.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

字符串:凯撒密码(洛谷P1914)

解析 只需将每一位ascll码加n即可 但要注意的是c的ascll码是有上限的 我一开始是这么写的&#xff1a; for(int i1;i<l;i){s[i] n;while(s[i]>z) s[i] - 26;printf("%c",s[i]);}结果&#xff1a; (真的是随便打的&#xff0c;不巧有些攻击性。。&#xff0…

.NET Core实战项目之CMS 第四章 入门篇-Git的快速入门及实战演练

写在前面上篇文章.NET Core实战项目之CMS 第三章 入门篇-源码解析配置文件及依赖注入我带着大家通过分析了一遍ASP.NET Core的源码了解了它的启动过程&#xff0c;然后又带着大家熟悉了一遍配置文件的加载方式&#xff0c;最后引出了依赖注入以及控制反转的概念&#xff01;如果…

高精度:麦森数*(洛谷P1045)

P1045 [NOIP2003 普及组] 麦森数 解析 看似只是正常的一个高精 然而 暗藏杀机 一开始随手那么一写 。。。 (即使用了快速幂)时间复杂度过于感人 后来我们发现&#xff1a; 第一问位数的计算不必真的算出来&#xff0c;只需把2的p次幂转化为10的k次幂即可&#xff08;具体请…

彼之蜜糖,吾之砒霜——聊聊软件开发中的最佳实践

“描述一个事物&#xff0c;唯有一个名词定义它的概念&#xff0c;唯有一个动词揭露它的行为&#xff0c;唯有一个形容词表现它的特征。要做的&#xff0c;就是用心去寻找那个名词、那个动词、那个形容词……”—— 福楼拜 (Gustave Flaubert)我想讲个故事。很久很久以前&#…

贪心: Array Splitting(数列分段)(洛谷CF1175D)

解析 这题可以转化一下&#xff1a; &#xff08;《神笔马良》。。。。&#xff09; 计算这些长方形对应下标的总加和 我们可以一层一层往上垒,假设第i层起始点为xi&#xff0c;总和为sumi&#xff0c;再设从1到i的前缀和为si 显然第一层x11&#xff0c;sum1sn 对于第二层x2&…

Docker最全教程——从理论到实战(一)

容器是应用走向云端之后必然的发展趋势&#xff0c;因此笔者非常乐于和大家分享我们这段时间对容器的理解、心得和实践。本篇教程持续编写了2个星期左右&#xff0c;只是为了大家更好地了解、理解和消化这个技术&#xff0c;能够搭上这波车。你可以关注我们的公众号“magiccode…

二分:路标设置(洛谷)

传送门. 解析 只需二分枚举空旷指数即可 对于单次判断的check函数&#xff0c;可以相当于n个路标把路面分成n1个间隔&#xff0c;而对于每个间隔[l,r]和空旷指数x&#xff08;边界已有路标&#xff09;&#xff0c;所需路标应为&#xff1a; (r-l-1)/x&#xff08;比如[2,5…

二分:[BJWC2008]秦腾与教学评估

洛谷传送门 解析 因为至多有一个单数 假设其位置为k&#xff0c;1-i的累加和为s[i] 则s[1]-s[k-1]全是偶数 s[k]-s[max]全是奇数 答案呈单调性&#xff0c;可以用二分算法 check函数&#xff08;计算前缀和&#xff09;也很容易用O&#xff08;n&#xff09;写出&#xff1a…

微软Azure予力Green Dot客服成就不凡

点击蓝字关注我碧点公司&#xff08;Green Dot&#xff09;是仔细聆听消费者心声&#xff0c;以消费者为导向的金融科技创新公司&#xff0c;致力于为大众带来高效、便捷与体验舒适的个人银行业务。Green Dot创造了预付借记卡产业&#xff0c;也是美国最大的可增值预付借记卡和…

倍增:st表(模板)(洛谷P3865)

[传送门](https://www.luogu.com.cn/problem/P38 解析 板子题最棒了 用mx[i][j]存储以i为起点&#xff0c;长度为2^j次方的区间内的max 分成前后两段&#xff0c;则可以得到递推式&#xff1a; mx[i][k]max(mx[i][k-1],mx[imi[k-1]][k-1]);而关于初始化&#xff0c;显然&…

首届大湾区 DevOps/微服务秋季分享会圆满落幕!

在科技迅速发展的时代&#xff0c;传统行业积极开展数字化转型以在激烈竞争中脱颖而出&#xff0c;新兴行业不停歇地验证业务模式以找准市场定位&#xff1b;软件与行业变得密不可分&#xff0c;各行各业如何快速响应软件需求&#xff0c;已经成为直接关系到企业核心利益的关键…

.NET Core实战项目之CMS 第五章 入门篇-Dapper的快速入门看这篇就够了

写在前面上篇文章我们讲了如在在实际项目开发中使用Git来进行代码的版本控制&#xff0c;当然介绍的都是比较常用的功能。今天我再带着大家一起熟悉下一个ORM框架Dapper&#xff0c;实例代码的演示编写完成后我会通过Git命令上传到GitHub上&#xff0c;正好大家可以再次熟悉下G…

倍增:喷泉 深度解析(洛谷P7167)

洛谷传送门 解析 什么破题 数据范围来看很明显最多到nlogn 首先&#xff0c;对于样例进行一下分析&#xff1a; 我们可以把它转化为一棵树&#xff1a; 每一个根都有对应的权&#xff0c;给你一个结点和加权和&#xff0c;问能爬到哪里 既然是树&#xff0c;自然要找爸爸…

P5163-WD与地图【tarjan,整体二分,线段树合并】

正题 题目链接:https://www.luogu.com.cn/problem/P5163 题目大意 给出nnn个点mmm条有向边&#xff0c;点有权值&#xff0c;要求支持操作 删除一条边修改一个点的权值求一个点所在强连通分量中前kkk大权值和 1≤n≤105,1≤m,q≤21051\leq n\leq 10^5,1\leq m,q\leq 2\times…

分布式系统(微服务架构)的一致性和幂等性问题相关概念解析

前言什么是分布式系统?关于这点其实并没有明确且统一的定义。在我看来,只要一个系统满足以下几点就可以称之为分布式系统系统由物理上不同分布的多个机器节点组成系统的多个节点通过网络进行通信,协调彼此之间的工作。系统作为整体统一对外提供服务,其分布式细节对客户端透明。…

hash:奶牛看地图(洛谷P3405 [USACO16DEC]Cities and States S)

洛谷传送门 解析 其实就是每组2个长度为2的字符串统计交叉相等的个数 每个序列可以用一个26进制的数来表示&#xff0c;总要加个标签&#xff0c;勉强算hash。。&#xff08;想叫《水题》 &#xff09; 最大值为26*26&#xff08;ZZ&#xff09; 所以可以开一个二维数组来进…

bfs:01迷宫(洛谷P1141)

洛谷传送门 解析 乍一看&#xff1a;bfs板子题 冰法师最棒了 然鹅 看了一眼数据范围 心中已有画面 《面 堂 发 黑》 怎么办嘞&#xff1f; 我们想到&#xff1a; 因为该题来与去的可逆性 我们搜一次后&#xff0c;这些点以后都不会再用到 而且每次覆盖到的所有点答案都是…

有关C# 8.0、.NET Framework 4.8与NET Standard 2.1的一个说明

早在本月12日&#xff0c;微软官方的.NET Blog发布了一篇名为《Building C# 8.0》的文章&#xff0c;介绍了很多C# 8.0的新特性。不过本文主要讨论的并不是C# 8.0的新特性&#xff0c;而是存在于这篇文章中的一段文字&#xff1a;Most of the C# 8.0 language features will ru…

2021牛客暑期多校训练营1 J-Journey among Railway Stations(线段树+思维转化)

J-Journey among Railway Stations 注意区间合并时是否可行信息的合并。 假设线段树当前左节点lll维护的区间是[L,mid][L,\text{mid}][L,mid]&#xff0c;右节点维护的区间为[mid1,R][\text{mid1},R][mid1,R] 如果它们分别可行&#xff0c;意味着可以从L→midL\to \text{mid}…

领域驱动设计,让程序员心中有码

“ 领域驱动设计的背后&#xff0c;需要开发者不能只专注于眼前功能的实现&#xff0c;而应该能够从全局去了解业务&#xff0c;并充分的将业务吃透&#xff0c;以可传承的知识的形式融入到开发过程中&#xff0c;只有这样才能促进产品更好的开发。”01—传统项目管理模式&…