This question has been asked before in a few forms but I cannot get any of the answers to work, I'm losing my hair and unsure if the problem is just that the solutions were from 2 years ago and things have changed.
How can I safely intercept the Response stream in a custom Owin Middleware - I based my code on this, it looks like it should work, but it doesn't
OWIN OnSendingHeaders Callback - Reading Response Body - seems to be a different OWIN version, because method signature doesn't work
What I want to do is write an OMC that can inspect the response stream from MVC.
What I did (amongst several other attempts), is to add an OMC that sets context.Response.Body to a MemoryStream, so I can rewind it and inspect what was written by downstream components:
public async Task Invoke(IDictionary<string, object> env)
{
IOwinContext context = new OwinContext(env);
// Buffer the response
var stream = context.Response.Body;
var buffer = new MemoryStream();
context.Response.Body = buffer;
.......
What I find is that the MemoryStream is always empty, unless I write to it from another OMC. So it seems that downstream OMCs are using my MemoryStream, but MVC responses are not, as if the OWIN pipeline completes before the request goes to MVC, but that's not right is it?
Complete code:
public partial class Startup
{
public void Configuration(IAppBuilder app)
{
ConfigureAuth(app);
app.Use(new ResponseExaminerMiddleware());
// Specify the stage for the OMC
//app.UseStageMarker(PipelineStage.Authenticate);
}
}
public class ResponseExaminerMiddleware
{
private AppFunc next;
public void Initialize(AppFunc next)
{
this.next = next;
}
public async Task Invoke(IDictionary<string, object> env)
{
IOwinContext context = new OwinContext(env);
// Buffer the response
var stream = context.Response.Body;
var buffer = new MemoryStream();
context.Response.Body = buffer;
await this.next(env);
buffer.Seek(0, SeekOrigin.Begin);
var reader = new StreamReader(buffer);
string responseBody = await reader.ReadToEndAsync();
// Now, you can access response body.
System.Diagnostics.Debug.WriteLine(responseBody);
// You need to do this so that the response we buffered
// is flushed out to the client application.
buffer.Seek(0, SeekOrigin.Begin);
await buffer.CopyToAsync(stream);
}
}
For what it's worth I also tried a suggestion where the response.Body stream is set to a Stream subclass, just so I could monitor what is written to the stream and bizarrely the Stream.Write method is called, but with an empty byte array, never any actual content...