1 .Net Core 2.X时代

使用EnableRewind倒带

public IActionResult Index()
{
    Request.EnableRewind();
    using (var reader = new StreamReader(Request.Body))
    {
        var body = reader.ReadToEnd();
        // Do something
        Request.Body.Seek(0, SeekOrigin.Begin);
        body = reader.ReadToEnd();
    }
    // More code
    return View("Index");
}

2 .NET Core 3.0时代

因为.NET Core 3.0 preview 6以后(6还是可以使用的), Microsoft.AspNetCore.Http.Internal不再是公有方法. 所以EnableRewind不能使用。

使用Enablebuffering

 public async Task<IActionResult> Index()
 {
     Request.EnableBuffering();
     using (var reader = new StreamReader(Request.Body, encoding: Encoding.UTF8))
     {
         var body = reader.ReadToEndAsync();
         // Do some processing with body…
         // Reset the request body stream position so the next middleware can read it
         Request.Body.Position = 0;
     }
     return View();
 }
 
 // 默认不支持同步方法:ReadToEnd()
 // 需要设置AllowSynchronousIO=true;
 // System.InvalidOperationException: 'Synchronous operations are disallowed. Call ReadAsync or set AllowSynchronousIO to true instead.'

3. 参考

  1. Reading request body in ASP.NET Core
  2. EnableRewind 源码
  3. Rereading Asp Net Core Request Bodies With Enablebuffering