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

时间:2021-01-26
本文章向大家介绍.net core 3.0 中间件或过滤器中读取post请求body方法,主要包括.net core 3.0 中间件或过滤器中读取post请求body方法使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

https://blog.csdn.net/diamondsos/article/details/103439530

.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);
        }

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

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

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

调试结果:

通过分析此时body发现stream长度为0

在请求到达过滤器时Steam已经被读取了,此时我们在过滤器中使用EnableBuffering并没有起作用,产生这种问题的具体原因我现在还没搞清楚。解决这个问题有个折中方案,在站点启动时设置以插入中间件的方式启用EnableBuffering,以达到在全局多次读取的目的。代码如下:

 public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
 {
 	  .....
 	  
      app.Use(next => context =>
      {
            context.Request.EnableBuffering();
            return next(context);
      });
      
      ......
 }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

修改过滤器中代码:

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);
  	 } 
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

再次请求即可读取到body数据,结果如下:

此外,3.0中默认禁用了AllowSynchronousIO,同步读取body的方式需要ConfigureServices中配置允许同步读取IO流,否则可能会抛出异常 Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.
根据使用的托管的服务进行配置或直接使用异步读取方式。

原文地址:https://www.cnblogs.com/cxxtreasure/p/14332734.html