异常处理,也可以做得很优雅。
?
一、前言
异常处理的重要性,老司机都清楚。
?
这篇文章,我们来理一下Dotnet Core异常处理的几种方式。
- Try Catch方式
- Exception Filter方式
- 内建的异常处理中间件
- 自定义的异常处理中间件
这是目前使用比较多的几种方式。其中,第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 块的性能会差很多。所以一般来说,一个基本的原则是,不要把try 、catch 作为程序的逻辑。
但是,如果我们需要又需要记录这个异常,该怎么办?
这时候,就可以利用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
?
?

微信公众号:老王Plus
扫描二维码,关注个人公众号,可以第一时间得到最新的个人文章和内容推送
本文版权归作者所有,转载请保留此声明和原文链接
(编辑:北几岛)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|