加入收藏 | 设为首页 | 会员中心 | 我要投稿 北几岛 (https://www.beijidao.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

Dotnet Core异常处理的优雅实践

发布时间:2021-05-21 07:53:40 所属栏目:大数据 来源: https://www.jb51.cc
导读:异常处理,也可以做得很优雅。 ? 一、前言 异常处理的重要性,老司机都清楚。 ? 这篇文章,我们来理一下Dotnet Core异常处理的几种方式。 Try Catch方式 Exception Filter方式 内建的异常处理中间件 自定义的异常处理中间件 这是目前使用比较多的几种方式。

微信公众号:老王Plus

扫描二维码,关注个人公众号,可以第一时间得到最新的个人文章和内容推送

本文版权归作者所有,转载请保留此声明和原文链接

(编辑:北几岛)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

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

?

一、前言

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

?

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

  1. Try Catch方式
  2. Exception Filter方式
  3. 内建的异常处理中间件
  4. 自定义的异常处理中间件

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

????为了防止不提供原网址的转载,特在这里加上原文链接:https://www.cnblogs.com/tiger-wang/p/13562817.html

二、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)
????????"error");
????else
????????"other?error");
}

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

catch?(Exception?ex)?when?(ex.InnerException?==?null)
{
????"error");
}
"other?error");
}

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

?

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

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

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

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

看代码:

string>?example_list?=?null;
????????var?item_count?=?example_list.Count();
????????catch?(Exception?ex)?when?(log(ex))
????{
????}
????"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,也是一个内置的用来处理异常的中间件,可以这样用:

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

@H_645_301@四、自定义的中间件

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

中间件的写法,我在前文一文说通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

?


?

    推荐文章
      热点阅读