I am trying to implement request-response logging middleware in asp.net core web API application. It's working as fine in normal flow. But on an exception in the application, seeing ObjectDisposed error
System.ObjectDisposedException: Cannot access a closed Stream.
Here are the code blocks:
public class LoggingMiddleware
{
private readonly RequestDelegate _next;
private readonly ILogger<RequestResponseLoggingMiddlewarecs> _logger;
public LoggingMiddleware(RequestDelegate requestDelegate, ILogger<LoggingMiddleware> logger)
{
_next = requestDelegate;
_logger = logger;
}
public async Task Invoke(HttpContext httpContext)
{
httpContext.Request.EnableBuffering();
var body = await new StreamReader(httpContext.Request.Body).ReadToEndAsync();
_logger.LogInformation($"Body: {body}");
httpContext.Request.Body.Position = 0;
//await _next(context);
var originalBodyStream = httpContext.Response.Body;
using (var responseBody = new MemoryStream())
{
var response = httpContext.Response;
response.Body = responseBody;
await _next(httpContext);
string responseBodyContent = null;
responseBodyContent = await ReadResponseBody(response);
await responseBody.CopyToAsync(originalBodyStream);
_logger.LogInformation(responseBodyContent);
}
}
}
In Startup.cs Configiration method
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseExceptionHandler("/error-developer");
}
else
{
app.UseExceptionHandler("/Error");
app.UseHsts();
}
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseMiddleware<RequestResponseLoggingMiddlewarecs>();
if (!env.IsDevelopment())
{
app.UseSpaStaticFiles();
}
app.UseRouting();
}
Error Controller
public class ErrorController : ControllerBase
{
[Route("/error-developer")]
public IActionResult Error([FromServices] IWebHostEnvironment webHostEnvironment)
{
var context = HttpContext.Features.Get<IExceptionHandlerFeature>();
var ex = context?.Error;
var isDev = webHostEnvironment.IsDevelopment();
return Problem(
detail: context.Error.StackTrace,
title: context.Error.Message);
}
[Route("/error")]
public IActionResult Error() => Problem();
}
Exception throwing at await responseBody.CopyToAsync(originalBodyStream);
Any thoughts/ideas, please?
Or any better way of implementing request-response logging and exception handling?