title: Serilog logging web-api methods, adding context properties inside middleware
body: <p>I've been struggling to log response body payload data with serilog, logging from middleware.
  I'm working on <em>WEB API Core</em> application, with <em>swagger</em> added to endpoints, and my goal is to log every endpoint call to a <em>.json</em> file with <em>serilog</em> (both request and response data). </p>
  
  <p>For <em>GET</em> requests, body of the response should be logged (added to serilog context as a property), and for POST requests, both body of request and response should be logged.
  I have created middleware and managed to properly retrieve data from request and response stream, and getting it as a string, but only the <em>"RequestBody"</em> is being logged properly. </p>
  
  <p>When debugging, I can see that reading request/response body works fine.</p>
  
  <p>Following is the code excerpt from Program->Main method:</p>
  
  <pre class="lang-cs prettyprint-override"><code>Log.Logger = new LoggerConfiguration()
      .ReadFrom.Configuration(configuration)
      .Enrich.FromLogContext()
      .CreateLogger();
  </code></pre>
  
  <p>and code in the middleware:</p>
  
  <pre class="lang-cs prettyprint-override"><code>public async Task Invoke(HttpContext context)
  {
      // Read and log request body data
      string requestBodyPayload = await ReadRequestBody(context.Request);
  
      LogContext.PushProperty("RequestBody", requestBodyPayload);
  
      // Read and log response body data
      var originalBodyStream = context.Response.Body;
      using (var responseBody = new MemoryStream())
      {
          context.Response.Body = responseBody;
          await _next(context);
          string responseBodyPayload = await ReadResponseBody(context.Response);
  
          if (!context.Request.Path.ToString().EndsWith("swagger.json") &amp;&amp; !context.Request.Path.ToString().EndsWith("index.html"))
          {
              LogContext.PushProperty("ResponseBody", responseBodyPayload);
          }
  
          await responseBody.CopyToAsync(originalBodyStream);
      }
  }
  
  private async Task&lt;string&gt; ReadRequestBody(HttpRequest request)
  {
      HttpRequestRewindExtensions.EnableBuffering(request);
  
      var body = request.Body;
      var buffer = new byte[Convert.ToInt32(request.ContentLength)];
      await request.Body.ReadAsync(buffer, 0, buffer.Length);
      string requestBody = Encoding.UTF8.GetString(buffer);
      body.Seek(0, SeekOrigin.Begin);
      request.Body = body;
  
      return $"{requestBody}";
  }
  
  private async Task&lt;string&gt; ReadResponseBody(HttpResponse response)
  {
      response.Body.Seek(0, SeekOrigin.Begin);
      string responseBody = await new StreamReader(response.Body).ReadToEndAsync();
      response.Body.Seek(0, SeekOrigin.Begin);
  
      return $"{responseBody}";
  }
  </code></pre>
  
  <p>As I mentioned, <em>"RequestBody"</em> is properly logged to file, but nothing for <em>"ResponseBody"</em> (not even added as a property)
  Appreciate any help.</p>