locked
ASP.Net web api: logging middleware: System.ObjectDisposedException: Cannot access a closed Stream RRS feed

  • Question

  • User441097800 posted

    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 Configuration 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?

    Wednesday, September 16, 2020 2:59 PM

All replies

  • User1312693872 posted

    Hi,PhaniVemireddy

    I tried your code but didn't get an error code like yours,  when you request the action,it will go into 

     app.UseMiddleware<RequestResponseLoggingMiddlewarecs>();

    But you didn't give the related class, and the problem may occur in it.

    So it will be more clear if you can offer more details for us to reproduce your problem.

    Best Regards,

    Jerry Cai

    Monday, September 21, 2020 9:07 AM
  • User-474980206 posted

    Most likely some code called Response,End()

    Monday, September 21, 2020 2:44 PM