.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.
根據使用的托管的服務進行配置或直接使用異步讀取方式。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM