.net core 3.0 中间件或过滤器中读取post请求body方法

.net core3.0中启动倒带方式由Request.EnableRewind()变为了 request.EnableBuffering(); 但是今天在过滤器中使用此方法时出现异常。原代码已经修改,下面以新建的项目做示例记录一下问题。新建WebApi项目,测试过滤器代码如下:

   public class TestFilter : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext context)
        {
            base.OnActionExecuting(context);
            var request = context.HttpContext.Request;
            //启动倒带方式
            request.EnableBuffering();
            if (request.Method.ToLower().Equals("post"))
            {
            	request.Body.Seek(0, SeekOrigin.Begin);
                using (var reader = new StreamReader(request.Body, Encoding.UTF8))
                {
                    var param = reader.ReadToEnd();
                }
                request.Body.Seek(0, SeekOrigin.Begin);
            }
          
        }
        public override void OnActionExecuted(ActionExecutedContext context)
        {
            base.OnActionExecuted(context);
        }

    }

启动项目站点,发送post请求

curl -X POST "http://localhost:5000/WeatherForecast" -H "accept: text/plain" -H "Content-Type: application/json" -d "{\"name\":\"string\",\"age\":\"string\"}"

调试结果:
在这里插入图片描述
通过分析此时body发现stream长度为0
在这里插入图片描述
在请求到达过滤器时Steam已经被读取了,此时我们在过滤器中使用EnableBuffering并没有起作用,产生这种问题的具体原因我现在还没搞清楚。解决这个问题有个折中方案,在站点启动时设置以插入中间件的方式启用EnableBuffering,以达到在全局多次读取的目的。代码如下:

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 {
 	  .....
 	  
      app.Use(next => context =>
      {
            context.Request.EnableBuffering();
            return next(context);
      });
      
      ......
 }

修改过滤器中代码:

public override void OnActionExecuting(ActionExecutingContext context)
{
	base.OnActionExecuting(context);
    var request = context.HttpContext.Request;
    
    if (request.Method.ToLower().Equals("post"))
    {
       request.Body.Seek(0, SeekOrigin.Begin);
       using (var reader = new StreamReader(request.Body, Encoding.UTF8))
       {
          var param = reader.ReadToEnd();
       }
        request.Body.Seek(0, SeekOrigin.Begin);
  	 } 
}

再次请求即可读取到body数据,结果如下:
在这里插入图片描述
此外,3.0中默认禁用了AllowSynchronousIO,同步读取body的方式需要ConfigureServices中配置允许同步读取IO流,否则可能会抛出异常 Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
根据使用的托管的服务进行配置或直接使用异步读取方式。

services.Configure<KestrelServerOptions>(x => x.AllowSynchronousIO = true)
                .Configure<IISServerOptions>(x=>x.AllowSynchronousIO = true);
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值