Dotnet Core异常处理的优雅实践

异常处理,也可以做得很优雅。

一、前言

异常处理的重要性,老司机都清楚。

这篇文章,我们来理一下Dotnet Core异常处理的几种方式。

  1. Try Catch方式

  2. Exception Filter方式

  3. 内建的异常处理中间件

  4. 自定义的异常处理中间件

这是目前使用比较多的几种方式。其中,第1、2种其实算是一种,是C#两个语言版本的东西。

二、Try Catch方式

这是最通常使用的一种方式。

看例子:

[HttpGet]
public IActionResult Get()
{try{List<string> example_list = null;var item_count  = example_list.Count();return Ok(item_count);}catch (Exception ex){return StatusCode(HttpContext.Response.StatusCode, ex.Message);}
}

有时候,我们可能需要处理多种异常。

catch (Exception ex)
{if(ex.InnerException == null)return StatusCode(HttpContext.Response.StatusCode, "error");elsereturn StatusCode(HttpContext.Response.StatusCode, "other error");
}

在C# 6以后,Try Catch加了一个过滤Exception Filter语法,可以在catch后跟一个条件语句。上面这个catch可以写为:

catch (Exception ex) when (ex.InnerException == null)
{return StatusCode(HttpContext.Response.StatusCode, "error");
}
catch (Exception ex)
{return StatusCode(HttpContext.Response.StatusCode, "other error");
}

在这个语法中,when后面是一个bool的判断,为true则进入catch块,为false则跳过。

在C#中,异常是从内向外逐层查找处理程序的,随着查找层数的增加,性能会逐渐降低。

概念上,try块的运行效率和不加try块的性能差不多,可以认为基本一致;但catch块的性能会差很多。所以一般来说,一个基本的原则是,不要把trycatch作为程序的逻辑。

但是,如果我们需要又需要记录这个异常,该怎么办?

这时候,就可以利用Exception Filter语法。

看代码:

[HttpGet]
public IActionResult Get()
{try{List<string> example_list = null;var item_count = example_list.Count();return Ok(item_count);}catch (Exception ex) when (log(ex)){}return StatusCode(HttpContext.Response.StatusCode, "error");
}private bool log(Exception ex)
{Debug.Print(ex.Message);return false;
}

在这个代码中,when条件后跟了一个返回bool的方法。我们可以在这个方法中进行异常的记录处理,然后返回false

为什么要返回false呢?是因为我们要记录异常,但为了性能的考虑,不希望代码进入到catch块。返回false后,程序执行了log方法,却又没进入到catch块。

当然,如果你想进入到catch块,那返回true就可以了。

嗯。这一段能看明白就行了,这不算是一个常规的解决办法,只能算一个旁门的小技巧。

三、内建的异常中间件

内建的异常处理,有两个。

一个是我们最常见的,在创建webapi类型的工程时,Startup.cs文件中已经默认生成好的:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{if (env.IsDevelopment()){app.UseDeveloperExceptionPage();}
}

这个app.UseDeveloperExceptionPage就是框架中用于显示异常的详细信息的中间件。

另一个,是app.UseExceptionHandler,也是一个内置的用来处理异常的中间件,可以这样用:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{app.UseExceptionHandler(para...);
}

参数可以是一个Endpoint,也可以是一个Action。实际应用时,还可以写成一个IApplicationBuilder的扩展。

四、自定义的中间件

如果对异常管理有很高的要求,自定义异常处理中间件,是最合适的一种方式。

中间件的写法,我在前文一文说通Dotnet Core的中间件中有详细的说明,这儿不再多说。

给一段例子看看:

public class CustomExceptionMiddleware
{private readonly RequestDelegate _next;private readonly ILogger<CustomExceptionMiddleware> _logger;public CustomExceptionMiddleware(RequestDelegate next, ILogger<CustomExceptionMiddleware> logger){_logger = logger;_next = next;}public async Task InvokeAsync(HttpContext httpContext){try{await _next(httpContext);}catch (Exception ex){_logger.LogError($"Exception occur: {ex}");await HandleExceptionAsync(httpContext, ex);}}private Task HandleExceptionAsync(HttpContext context, Exception exception){context.Response.ContentType = "application/json";context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;return context.Response.WriteAsync(new CustomError(){StatusCode = context.Response.StatusCode,Message = "custom middleware error."}.ToString());}
}

使用时,就在Configure里引入即可。

(全文完)

本文的代码已上传到Github,位置在:https://github.com/humornif/Demo-Code/tree/master/0023/demo/demo

喜欢就来个三连,让更多人因你而受益

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

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

相关文章

jdbc的预处理中如何处理模糊查询

一&#xff1a;问题描述 当我们用模糊查询的时候 想向sql语句中的&#xff1f;赋值&#xff0c;这时会发现我们的sql语句一直报错 二:解决方法 package com.wyj.one;import com.wyj.pojo.Role; import com.wyj.utils.JdbcutilsBydruid; import org.apache.commons.dbutils.Q…

『软件工程6』详解软件项目管理之软件范围与估算

软件项目管理——软件范围与估算一、软件项目计划1、目标2、步骤二、软件范围1、软件范围定义2、软件范围——引例三、影响估算的因素四、软件项目资源1、软件项目资源构成2、分析图3、人力资源4、硬件资源5、软件工具6、可复用构件五、软件工作量与成本的估算1、基于LOC估算工…

【翻译】.NET 5 Preview8发布

今天&#xff0c;.NET 5预览8发布了&#xff0c;对于.NET5.0的功能开发已经完成了&#xff0c;这必须要排除待处理的bug&#xff0c;预览8是最后一次预览版本。预计11月正式的.NET5.0版本发布之前还将发布两个正式之前的候选版本&#xff0c;这篇文章描述了.NET5.0版本中的一系…

『软件工程7』详解软件项目管理之风险分析与管理

软件项目管理——风险分析与管理一、风险及风险管理的含义1、风险的含义2、风险管理含义二、被动和主动的风险策略1、被动风险策略2、主动风险策略三、风险的特性四、风险的类型1、项目风险2、技术风险3、商业风险五、风险管理的步骤1、风险识别2、风险预测3、风险缓解、监控和…

7-1 页面置换算法--FIFO (50 分)(思路详解)

一:题目 先初始化页面大小&#xff0c;和物理块数。连续输入页面的逻辑地址&#xff0c;以“-1”作为结束标志&#xff0c;采用FIFO页面置换算法、固定分配局部置换分配策略。输出该页面的页号和页内位移&#xff0c;若该页不在内存&#xff0c;并且还有剩余的物理块&#xff…

7-2 页面置换算法--LRU (50 分)

一:题目(思路详解运行时错误解决) 先初始化页面大小&#xff0c;和物理块数。连续输入页面的逻辑地址&#xff0c;以“-1”作为结束标志&#xff0c;采用LRU页面置换算法、固定分配局部置换分配策略。输出该页面的页号和页内位移&#xff0c;若该页不在内存&#xff0c;并且还…

『软件测试3』八大典型的黑盒测试方法已来袭,快快接住!

文章目录一、等价类划分法1、定义2、等价类划分法步骤3、设计测试用例步骤4、案例&#xff1a;学生选修课程二、边界值分析法1、边界值分析法概述2、设计测试用例3、边界值设计原则三、错误推测法1、错误推测法概述2、错误推测法基本思想四、因果图设计法1、因果图设计法概述2、…

使用Jenkins来发布和代理.NetCore项目

Back toStudy!注&#xff1a;书接上文&#xff0c;上回《【CI/CD系列】使用Docker安装Jenkins》咱们说到了使用Docker镜像的方式&#xff0c;来建立Jenkins服务&#xff0c;用来持续集成和持续发布项目&#xff0c;但是上一篇文章有两个问题&#xff1a;01创建的容器不能操作和…

数据库课设(足球联赛管理系统)

一&#xff1a;前言 如果有关注博主的粉丝&#xff0c;可能会发现贴心杰又缺更好几天了&#xff0c;但是我是宠粉杰啊&#xff0c;怎么可能会忘了我的宝贝粉丝呢&#xff0c;只不过是临近期末&#xff0c;各种大作业课设如期而至&#xff0c;这几天我在写数据库课设&#xff0…

.NET Core实用技巧(一)如何将EF Core生成的SQL语句显示在控制台中

前言笔者最近在开发和维护一个.NET Core 项目&#xff0c;其中使用几个非常有意思的.NET Core 相关的扩展&#xff0c;在此总结整理一下。EF Core 性能调优如果你的项目中使用了 EF Core, 且正在处于性能调优阶段&#xff0c;那么了解 EF Core 生成的 SQL 语句是非常关键的。那…

695.岛屿的最大面积(026)BFS

二:思路 1.这里的遍历数据方式为BFS广度遍历 2.当我们遇到一个‘1’的时候,我们就遍历他的左右上下&#xff08;邻接点&#xff09;&#xff0c;如果是1那就入队&#xff0c;直到队列 为空为止。 3.我们记录每个岛屿的面积是采用 我们设置初始值为1&#xff0c;当每遇到一个邻…

『软件工程8』软件项目进度安排与跟踪,一招学会计算关键路径

项目进度安排与跟踪一、项目进度安排的定义及原则1、进度安排的定义2、进度安排的基本原则二、通信开销1、通信开销的定义2、通信路径计算3、案例分析三、工作量分配1、40-20-40规则2、工作量分配图例3、工作量分布推荐四、项目进度安排方法1、关键路径方法(CPM,Critical Path …

await,async 我要把它翻个底朝天,这回你总该明白了吧

一&#xff1a;背景1. 讲故事await&#xff0c;async 这玩意的知识点已经被人说的烂的不能再烂了&#xff0c;看似没什么好说的&#xff0c;但我发现有不少文章还是从理论上讲述了这两个语法糖的用法&#xff0c;懂得还是懂&#xff0c;不懂的看似懂了过几天又不懂了&#xff0…

栈在前端中的应用,顺便再了解下深拷贝和浅拷贝!

详解栈在前端中的应用一、栈是什么二、栈的应用场景三、前端与栈&#xff1a;深拷贝与浅拷贝1、JS数据类型&#xff08;1&#xff09;js数据类型的分类&#xff08;2&#xff09;js数据类型的定义和存储方式&#xff08;3&#xff09;js数据类型的判断方式2、深究浅拷贝和深拷贝…

【招聘(深圳)】轻岁 诚聘.NET Core开发

招聘简介为了支撑公司互联网的战略转型&#xff0c;我们将基于.NET Core K8S/TKE 腾讯云云函数的微服务架构&#xff0c;打造高性能、高并发、高扩展的基础平台&#xff0c;同时基于该平台进行应用开发&#xff0c;包括Web端&#xff0c;移动端&#xff08;微信公众号、小程序…

详解链表在前端的应用,顺便再弄懂原型和原型链!

链表在前端中的应用一、链表VS数组二、JS中的链表三、前端与链表&#xff1a;JS中的原型链1、原型是什么&#xff1f;2、原型链是什么&#xff1f;3、原型链长啥样&#xff1f;&#xff08;1&#xff09;arr → Array.prototype → Object.prototype → null&#xff08;2&…

计网课设 模拟实验拓扑

一:前言 幸福的是考完两科了&#xff0c;抽出时间赶紧赶赶课设&#xff0c;两周遇到了好多事&#xff0c;开心的&#xff0c;烦心的&#xff0c;一堆堆的压过来&#xff0c;但庆幸自己迷失不太久&#xff0c;又能继续学习了 二&#xff1a;实验概览 1:实验拓扑图 2:实验要求…

快醒醒,C# 9 中又来了一堆关键词 init,record,with

一&#xff1a;背景1. 讲故事.NET5 终于在 2020-08-25 也就是前天发布了第八个预览版&#xff0c;这么多的预览版搞得我都麻木了&#xff0c;接踵而来的就是更多的新特性加入到了 C# 9 中&#xff0c;既然还想呆在这条船上&#xff0c;得继续硬着头皮学习哈&#xff0c;这一篇跟…

7-1 字母统计图 (10 分)(思路+详解)

一&#xff1a;题目 摆放在面前的是一小段英文文章。 afeng希望你能帮他统计一下每个小写字母出现的次数。 最后再以柱状图的形式(参照输出样例)输出出来。 输入格式: 输入第一行为一个正整数N(N<100)&#xff0c;表示文章的行数。 随后为N行文本。 输出格式: 由若干行组…

了解js基础知识中的作用域和闭包以及闭包的一些应用场景,浅析函数柯里化

js基础知识中的作用域和闭包一、作用域1、作用域、自由变量简介&#xff08;1&#xff09;作用域定义&#xff08;2&#xff09;作用域实例演示&#xff08;3&#xff09;自由变量定义&#xff08;4&#xff09;自由变量实例演示2、作用域链简介&#xff08;1&#xff09;作用域…