ASP.NET Core 中讀取 Request.Body 的正確姿勢


ASP.NET Core 中的 Request.Body 雖然是一個 Stream ,但它是一個與眾不同的 Stream —— 不允許 Request.Body.Position=0 ,這就意味着只能讀取一次,要想多次讀取,需要借助 MemoryStream ,詳見博問 asp.net core中2次讀取Request.Body的問題 

using (var buffer = new MemoryStream())
{
    Request.Body.CopyTo(buffer);
    buffer.Position = 0;
    buffer.CopyTo(writer.BaseStream);
    Console.WriteLine("Request.Body:");
    buffer.Position = 0;
    buffer.CopyTo(Console.OpenStandardOutput());
} 

昨天讀了博文 Reading request body in ASP.NET Core 之后得知在 ASP.NET Core 2.0 中已經針對這個問題提供了解決方法 —— EnableRewind() ,只要啟用倒帶功能,就可以讓  Request.Body 回歸正常 Stream 。

使用非常簡單,引用命名空間 Microsoft.AspNetCore.Http.Internal ,調用方法 Request.EnableRewind()  即可,下面我們用簡單的示例代碼體驗一下

public class HomeController : Controller
{
    public IActionResult Index()
    {
        Request.EnableRewind();

        Console.WriteLine("Request.Body1:");
        Request.Body.Position = 0;
        Request.Body.CopyTo(Console.OpenStandardOutput());
        Console.WriteLine();

        Console.WriteLine("Request.Body2:");
        Request.Body.Position = 0;
        Request.Body.CopyTo(Console.OpenStandardOutput());
        Console.WriteLine();

        return Ok();
    }
}

啟動上面的 ASP.NET Core 站點,然后用 curl 命令發出請求

curl -X POST -d 'Hello World' localhost:5000

控制台就會輸出期望的結果

Request.Body1:
Hello World
Request.Body2:
Hello World

EnableRewind 有 2 個參數 bufferThreshold 與 bufferLimit 。 bufferThreshold 設置的是 Request.Body 最大緩存字節數(默認是30K),超出這個閾值的字節會被寫入磁盤;bufferLimit 設置的是 Request.Body 允許的最大字節數(默認值是null),超出這個限制,就會拋出異常  System.IO.IOException 。

EnableRewind 的實現源代碼見 BufferingHelper.cs

更新:.NET Core 3.0 中 EnableRewind 被改名為 EnableBuffering 。


免責聲明!

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



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