I want to write Custom Middleware in my ASP.NET Core 1.0 project which will replace original framework's Http Response Stream to my own, so I will be able to perform read / seek / write operations on it (first 2 are not possible on the original stream) in the further code i.e. in Actions or Filters.
I've started with the following code:
public class ReplaceStreamMiddleware
{
protected RequestDelegate NextMiddleware;
public ReplaceStreamMiddleware(RequestDelegate next)
{
NextMiddleware = next;
}
public async Task Invoke(HttpContext httpContext)
{
using (var responseStream = new MemoryStream())
{
var fullResponse = httpContext.Response.Body;
httpContext.Response.Body = responseStream;
await NextMiddleware.Invoke(httpContext);
responseStream.Seek(0, SeekOrigin.Begin);
await responseStream.CopyToAsync(fullResponse);
}
}
}
The problem with the following code is that sometimes the fullResponse stream is already closed at the time of invoking await responseStream.CopyToAsync(fullResponse); so it throws an exception Cannot access a closed Stream.
This weird behaviour is easy to observe when I load the page in the browser and then refresh, before it loads completely.
I would like to know:
- why this happens?
- how to prevent it?
- is my solution a good idea or there is another way to replace response stream?