title: How to read ASP.NET Core Response.Body?
body: <p>I've been struggling to get the <code>Response.Body</code> property from an ASP.NET Core action and the only solution I've been able to identify seems sub-optimal.  The solution requires swapping out <code>Response.Body</code> with a <code>MemoryStream</code> while reading the stream into a string variable, then swapping it back before sending to the client.  In the examples below, I'm trying to get the <code>Response.Body</code> value in a custom middleware class.  <code>Response.Body</code> is a <em>set</em> only property in ASP.NET Core for some reason?  Am I just missing something here, or is this an oversight/bug/design issue?  Is there a better way to read <code>Response.Body</code>?</p>
  
  <p><strong>Current (sub-optimal) solution:</strong></p>
  
  <pre><code>public class MyMiddleWare
  {
      private readonly RequestDelegate _next;
  
      public MyMiddleWare(RequestDelegate next)
      {
          _next = next;
      }
  
      public async Task Invoke(HttpContext context)
      {
          using (var swapStream = new MemoryStream())
          {
              var originalResponseBody = context.Response.Body;
  
              context.Response.Body = swapStream;
  
              await _next(context);
  
              swapStream.Seek(0, SeekOrigin.Begin);
              string responseBody = new StreamReader(swapStream).ReadToEnd();
              swapStream.Seek(0, SeekOrigin.Begin);
  
              await swapStream.CopyToAsync(originalResponseBody);
              context.Response.Body = originalResponseBody;
          }
      }
  }  
  </code></pre>
  
  <p><strong>Attempted solution using EnableRewind():</strong>
  This only works for <code>Request.Body</code>, not <code>Response.Body</code>.  This results in reading an empty string from <code>Response.Body</code> rather than the actual response body contents.</p>
  
  <p><em>Startup.cs</em></p>
  
  <pre><code>public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, IApplicationLifetime appLifeTime)
  {
      loggerFactory.AddConsole(Configuration.GetSection("Logging"));
      loggerFactory.AddDebug();
  
      app.Use(async (context, next) =&gt; {
          context.Request.EnableRewind();
          await next();
      });
  
      app.UseMyMiddleWare();
  
      app.UseMvc();
  
      // Dispose of Autofac container on application stop
      appLifeTime.ApplicationStopped.Register(() =&gt; this.ApplicationContainer.Dispose());
  }
  </code></pre>
  
  <p><em>MyMiddleWare.cs</em></p>
  
  <pre><code>public class MyMiddleWare
  {
      private readonly RequestDelegate _next;
  
      public MyMiddleWare(RequestDelegate next)
      {
          _next = next;
      }
  
      public async Task Invoke(HttpContext context)
      {
          await _next(context);
          string responseBody = new StreamReader(context.Request.Body).ReadToEnd(); //responseBody is ""
          context.Request.Body.Position = 0;
      }
  }  
  </code></pre>