Search code examples
c#asp.netasp.net-web-apiowinmiddleware

IOwinResponse is empty


public class ErrorHandler : DelegatingHandler
{
    async protected override Task<HttpResponseMessage> SendAsync(
            HttpRequestMessage request, CancellationToken cancellationToken)
    {
        HttpResponseMessage response = await base.SendAsync(request, cancellationToken);
        switch (response.StatusCode)
        {
            case HttpStatusCode.InternalServerError:
                var error = await response.Content.ReadAsAsync<HttpError>();
                response.StatusCode = HttpStatusCode.InternalServerError;
                response.Content = new StringContent(ErrorTypeMessage.InternalServerError.ToString() + error["ExceptionMessage"] + " | " + error["StackTrace"], System.Text.Encoding.UTF8, "text/plain");
                ; break;
        }
        return response;
    }
}

as above I use a handler to handle errors and use a custom middleware to log errors as follows.

 public sealed class MyLogger : OwinMiddleware
{

    public MyLogger(OwinMiddleware next)
        : base(next)
    {
    }

    public override async Task Invoke(IOwinContext context)
    {
        var record = new ApiEntry
        {
            CallerIdentity = identity
        };

        await Task.Run(() =>
        {
            record.Request = new StreamReader(context.Request.Body).ReadToEnd();

            byte[] requestData = Encoding.UTF8.GetBytes(record.Request);
            context.Request.Body = new MemoryStream(requestData);
        });

        await Next.Invoke(context);

        using (var buffer = new MemoryStream())
        {
            var stream = context.Response.Body;
            context.Response.Body = buffer;

            buffer.Seek(0, SeekOrigin.Begin);
            using (var bufferReader = new StreamReader(buffer))
            {
                record.Response = await bufferReader.ReadToEndAsync();
                buffer.Seek(0, SeekOrigin.Begin);
                await buffer.CopyToAsync(stream);
                context.Response.Body = stream;
            }
        }

         //Record ApiEntry to a file as xml

    }

}

I m trying to read the error response which was set in the handler from the middleware. But record.Responseis empty. Can I access httpResponseMessage inside middleware or is there a easy way to do that?


Solution

  • Thanks Nikoshi as you said I also couldn't find a relationship between HttpResponseMessage and IOwinResponse. Finally i was able to resolve that using

    DelegatingHandler

    implement a custom handler using a DelegatingHandler.