博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Dotnet Core异常处理的优雅实践
阅读量:4034 次
发布时间:2019-05-24

本文共 3537 字,大约阅读时间需要 11 分钟。

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

一、前言

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

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

  1. Try Catch方式

  2. Exception Filter方式

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

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

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

二、Try Catch方式

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

看例子:

[HttpGet]public IActionResult Get(){    try    {        List
 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");    else        return 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
 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的扩展。

四、自定义的中间件

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

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

给一段例子看看:

public class CustomExceptionMiddleware{    private readonly RequestDelegate _next;    private readonly ILogger
 _logger;    public CustomExceptionMiddleware(RequestDelegate next, ILogger
 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://yezdi.baihongyu.com/

你可能感兴趣的文章
各种排序算法的分析及java实现
查看>>
SSH框架总结(框架分析+环境搭建+实例源码下载)
查看>>
js弹窗插件
查看>>
自定义 select 下拉框 多选插件
查看>>
js判断数组内是否有重复值
查看>>
js获取url链接携带的参数值
查看>>
gdb 调试core dump
查看>>
gdb debug tips
查看>>
arm linux 生成火焰图
查看>>
jtag dump内存数据
查看>>
linux和windows内存布局验证
查看>>
linux config
查看>>
linux insmod error -1 required key invalid
查看>>
linux kconfig配置
查看>>
linux不同模块completion通信
查看>>
linux printf获得时间戳
查看>>
C语言位扩展
查看>>
linux dump_backtrace
查看>>
linux irqdebug
查看>>
git 常用命令
查看>>