发现AspNet.Core版本控制库Bug一枚,你还想入坑?
我,博客写作小白一枚,注册账号多年却未曾留下只言片语,在潜水的这些年里从大家的博客中收获了很多新的知识忽觉惶恐心有不安,是时候给大家分享一些我的经验和教训了。嗯嗯,实话告诉大家前面的话的都是来凑字数的,哈哈,其实就是懒^_^,第一次写如有叙述不清的地方还请大家多包涵
问题复现
问题的复现一两句话也不好说也说不清楚,如果单独使用Microsoft.AspNetCore.Mvc.Versioning库是不会出现问题的,这个问题的复现需要结合其他库的。还是用代码来详细阐述吧
代码真心不多,大家看完后是否也是这种想法呢,简单的说下这段代码意图,在请求接口api/v1/values/{id}时出现未处理的异常,则由异常处理中间件重写请求到/error/page/500接口(即:输出字符串exception),接下来我将用调试的方式让大家来见证这个问题。
通过上图我们发现如下的现象:
第一次请求:异常中间件并没有成功的将请求重写到/errorpage/500接口,而是重写到了原来的请求上去,所以抛出了2次异常。
第二次请求,异常中间件则成功的将请求重写到/error/www.wandiansoft.com page/500接口,所以抛出了1次异常,并输入了字符串exception。
问题解决
这个问题其实是由Microsoft.AspNetCore.Mvc.Versioning库第一次请求到达后会将正确的action缓存到当前上下文的Items中(即:HttpContext.Items),当action执行完成(不管是否出现未出的异常)后并未清理当前上下文中缓存数据,这将导致所有类似于异常处理中间件这种在一次请求中存在二次重入http管道的中间件出现异常。我们只需要继承DefaultApiVersionRoutePolicy重写OnSingleMatch方法在action执行完成后清理掉items中的缓存即可
我,博客写作小白一枚,注册账号多年却未曾留下只言片语,在潜水的这些年里从大家的博客中收获了很多新的知识忽觉惶恐心有不安,是时候给大家分享一些我的经验和教训了。嗯嗯,实话告诉大家前面的话的都是来凑字数的,哈哈,其实就是懒^_^,第一次写如有叙述不清的地方还请大家多包涵
问题复现
问题的复现一两句话也不好说也说不清楚,如果单独使用Microsoft.AspNetCore.Mvc.Versioning库是不会出现问题的,这个问题的复现需要结合其他库的。还是用代码来详细阐述吧
代码真心不多,大家看完后是否也是这种想法呢,简单的说下这段代码意图,在请求接口api/v1/values/{id}时出现未处理的异常,则由异常处理中间件重写请求到/error/page/500接口(即:输出字符串exception),接下来我将用调试的方式让大家来见证这个问题。
通过上图我们发现如下的现象:
第一次请求:异常中间件并没有成功的将请求重写到/errorpage/500接口,而是重写到了原来的请求上去,所以抛出了2次异常。
第二次请求,异常中间件则成功的将请求重写到/error/www.wandiansoft.com page/500接口,所以抛出了1次异常,并输入了字符串exception。
问题解决
这个问题其实是由Microsoft.AspNetCore.Mvc.Versioning库第一次请求到达后会将正确的action缓存到当前上下文的Items中(即:HttpContext.Items),当action执行完成(不管是否出现未出的异常)后并未清理当前上下文中缓存数据,这将导致所有类似于异常处理中间件这种在一次请求中存在二次重入http管道的中间件出现异常。我们只需要继承DefaultApiVersionRoutePolicy重写OnSingleMatch方法在action执行完成后清理掉items中的缓存即可