.net core异常中间件的使用
正文
if (env.isdevelopment()) { app.usedeveloperexceptionpage(); }
这样写入中间件哈,那么在env环境下就会去执行usedeveloperexceptionpage。
public static iapplicationbuilder usedeveloperexceptionpage(this iapplicationbuilder app) { if (app == null) { throw new argumentnullexception(nameof(app)); } return app.usemiddleware<developerexceptionpagemiddleware>(); }
那么我们应该去看developerexceptionpagemiddleware中间件哈。
那么这里介绍它是如何能够捕获其他中间件的异常的哈。
里面的invoke:
其实它的操作是很简单的,直接在外面套了try catch。
里面的异常处理怎么处理的可以直接去看developerexceptionpagemiddleware 中间件,里面的操作也比较简单处理。
测试:
[httpget] public int getservice([fromservices]iselfservice selfservice) { throw new system.exception("错误"); return 1; }
结果:
因为上面说了,这个是dev环境下,那么生产环境不能直接给用户看到错误信息。
正式环境:
app.useexceptionhandler("/error");
将错误转移到/error 处理。具体useexceptionhandler细节篇里面介绍,有许多可以借鉴的地方。
[apicontroller] [route("[controller]")] public class errorcontroller : controller { public ilogger<errorcontroller> _logger; public errorcontroller(ilogger<errorcontroller> logger) { this._logger = logger; } public iactionresult index() { var exceptionhandlerpathfeature = httpcontext.features.get<iexceptionhandlerpathfeature>(); var ex = exceptionhandlerpathfeature?.error; var knownexception = ex as iknownexception; if (knownexception == null) { _logger.logerror(ex, ex.message); knownexception = knownexception.unknow; } else { knownexception = knownexception.fromknowexception(knowexception); } return view(knownexception); } }
视图:
<html> <head> </head> <body> <div> 错误码: @model.errorcode </div> <div> 错误信息: @model.message </div> </body> </html>
iknownexception:
public interface iknownexception { public string message { get; } public int errorcode { get; } public object[] errordata { get; } }
knownexception:
public class knownexception : iknownexception { public string message { get; private set; } public int errorcode { get; private set; } public object[] errordata { get; private set; } public readonly static iknownexception unknow = new knownexception { message = "未知错误", errorcode = 99 }; public static iknownexception fromknowexception(iknownexception exception) { return new knownexception{message = exception.message, errorcode = exception.errorcode, errordata = exception.errordata}; } }
测试1:
[httpget] public int getservice([fromservices]iselfservice selfservice) { throw new system.exception("错误"); return 1; }
这种属于未知异常,结果:
现在弄一个支付异常:
public class payerrorexception : exception, iknownexception { public payerrorexception(string message, int errorcode, params object[] errordata): base(message) { this.errorcode = errorcode; this.errordata = errordata; } public int errorcode { get;private set; } public object[] errordata { get;private set; } }
测试2:
[httpget] public int getservice([fromservices]iselfservice selfservice) { throw new payerrorexception("支付错误",405,null); return 1; }
将异常处理放入到中间件分支中。
app.useexceptionhandler(errapp => { errapp.run(async context => { var exceptionhandlerpathfeature = context.features.get<iexceptionhandlerpathfeature>(); iknownexception knownexception = exceptionhandlerpathfeature.error as iknownexception; if (knownexception == null) { var logger = context.requestservices.getservice<ilogger<myexceptionfilterattribute>>(); logger.logerror(exceptionhandlerpathfeature.error, exceptionhandlerpathfeature.error.message); knownexception = knownexception.unknown; context.response.statuscode = statuscodes.status500internalservererror; } else { knownexception = knownexception.fromknownexception(knownexception); context.response.statuscode = statuscodes.status200ok; } var jsonoptions = context.requestservices.getservice<ioptions<jsonoptions>>(); context.response.contenttype = "application/json; charset=utf-8"; await context.response.writeasync(system.text.json.jsonserializer.serialize(knownexception, jsonoptions.value.jsonserializeroptions)); }); });
效果一样就不演示了。如果是已知异常错误码应该为200,一个是500异常是系统无法处理,系统错误,但是已知错误是属于系统正常处理。另一个是监控系统,认为报500错误,是会持续放出系统警告。
还有一种局部异常,只在mvc中生效,而不是全局生效:
public class myexceptionfilter : iexceptionfilter { public void onexception(exceptioncontext context) { iknownexception knownexception = context.exception as iknownexception; if (knownexception == null) { var logger = context.httpcontext.requestservices.getservice<ilogger<myexceptionfilterattribute>>(); logger.logerror(context.exception, context.exception.message); knownexception = knownexception.unknown; context.httpcontext.response.statuscode = statuscodes.status500internalservererror; } else { knownexception = knownexception.fromknownexception(knownexception); context.httpcontext.response.statuscode = statuscodes.status200ok; } context.result = new jsonresult(knownexception) { contenttype = "application/json; charset=utf-8" }; } }
在mvc 中注册:
services.addmvc(mvcoptions => { mvcoptions.filters.add<myexceptionfilter>(); }).addjsonoptions(jsonoptions => { jsonoptions.jsonserializeroptions.encoder = system.text.encodings.web.javascriptencoder.unsaferelaxedjsonescaping; });
最后介绍一种,只作用于某个控制器,或者action:
public class myexceptionfilterattribute : exceptionfilterattribute { public override void onexception(exceptioncontext context) { iknownexception knownexception = context.exception as iknownexception; if (knownexception == null) { var logger = context.httpcontext.requestservices.getservice<ilogger<myexceptionfilterattribute>>(); logger.logerror(context.exception, context.exception.message); knownexception = knownexception.unknown; context.httpcontext.response.statuscode = statuscodes.status500internalservererror; } else { knownexception = knownexception.fromknownexception(knownexception); context.httpcontext.response.statuscode = statuscodes.status200ok; } context.result = new jsonresult(knownexception) { contenttype = "application/json; charset=utf-8" }; } }
查看一下exceptionfilterattribute头部:
[attributeusage(attributetargets.class | attributetargets.method, allowmultiple = true, inherited = true)] public abstract class exceptionfilterattribute : attribute, iasyncexceptionfilter, iexceptionfilter, iorderedfilter
上面标志了可以放于类上也可以放于方法上。所以可以放至在controller上,也可以action上,看需求了。
结
以上就是.net core异常中间件的使用的详细内容,更多关于.net core异常中间件的资料请关注其它相关文章!
上一篇: ASP.NET Core文件压缩常见使用误区(最佳实践)
下一篇: 打了鸡血的老婆
推荐阅读
-
傻瓜式解读koa中间件处理模块koa-compose的使用
-
关于jsp页面使用jstl的异常分析
-
.net core项目中常用的几款类库详解(值得收藏)
-
asp.net使用Socket.Send发送信息及Socket.SendFile传输文件的方法
-
asp.net使用DataSet的ReadXml读取XML文件及Stream流的方法
-
asp.net GridView中使用RadioButton单选按钮的方法
-
ASP.NET MVC中使用jQuery时的浏览器缓存问题详解
-
SQL Server中调用C#类中的方法实例(使用.NET程序集)
-
解决 .NET Core 中 GetHostAddressesAsync 引起的 EnyimMemcached 死锁问题
-
ASP.NET Core部署前期准备 使用Hyper-V安装Ubuntu Server 16.10