title: C# DotNet Core Middleware Wrap Response
body: <p>I have a simple controller action which looks like:</p>
  
  <pre><code>    public Task&lt;IEnumerable&lt;Data&gt;&gt; GetData()
      {
          IEnumerable&lt;Data&gt; data = new List&lt;Data&gt;();
          return data;
      }
  </code></pre>
  
  <p>I want to be able to inspect the return value from within the middleware so the JSON would look something like</p>
  
  <pre><code>{
    "data": [
    ],
    "apiVersion": "1.2",
    "otherInfoHere": "here"
  }
  </code></pre>
  
  <p>So my payload always is within <code>data</code>. I know I can do this at a controller level but I don't wan to have to do it on every single action. I would rather do it in middleware once for all.</p>
  
  <p>Here is an example of my middleware:</p>
  
  <pre><code>public class NormalResponseWrapper
  {
      private readonly RequestDelegate next;
  
      public NormalResponseWrapper(RequestDelegate next)
      {
          this.next = next;
      }
  
      public async Task Invoke(HttpContext context)
      {                
          var obj = context;
          // DO something to get return value from obj
          // Create payload and set data to return value
  
          await context.Response.WriteAsync(/*RETURN NEW PAYLOAD HERE*/);
      }
  </code></pre>
  
  <p>Any ideas?</p>
  
  <p><strong>Got the value now but it's to late to return it</strong></p>
  
  <pre><code>        try
          {
              using (var memStream = new MemoryStream())
              {
                  context.Response.Body = memStream;
                  await next(context);
                  memStream.Position = 0;
                  object responseBody = new StreamReader(memStream).ReadToEnd();
                  memStream.Position = 0;
                  await memStream.CopyToAsync(originalBody);
                  // By now it is to late, above line sets the value that is going to be returned
                  await context.Response.WriteAsync(new BaseResponse() { data = responseBody }.toJson());
              }
  
          }
          finally
          {
              context.Response.Body = originalBody;
          }
  </code></pre>