• .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.
    根据使用的托管的服务进行配置或直接使用异步读取方式。

  • 相关阅读:
    PHP操作Memcache基本函数
    sublime text 设置
    获取客户端IP地址经纬度所在城市
    php 中文转拼音首字母问题
    php分类
    php +mysql 添加 删除 修改 insert into delete update
    php+mysql 内联接 和 子查询
    mysql count max min 语句用法
    mysql 查询语句
    非常不错的MySQL优化的8条经验
  • 原文地址:https://www.cnblogs.com/cxxtreasure/p/14332734.html
Copyright © 2020-2023  润新知