Read Request and Response body in ASP.NET Core

Today in this article, we will see how to Read Request and Response body in ASP.NET Core. Reading REST Request and Response could be non-functional requirements for your project addressing some of your basic needs like helping in troubleshooting or performance monitoring etc.

However, it may not be recommended to log all requests and responses but the fact is that could also be a possible requirement.

There could be multiple approaches to address this requirement but I found the middleware approach as the easiest and preferred one.

Today in this article, we will cover below aspects,


There were a few issues with the POST method dealing with ”Invalid Model State” while passing the model object but with a small tweak I was able to resolve those issues.

The below technique also helps to keep your Request and Response model state valid and intact while using middleware to intercept the Request and Response.

Let’s dive into the code,

Getting started

  • Please create a WebAPI project using the .NET Core 2.2 template. Here I have used the Visual Studio 2019 Preview version.

Create Middleware for Reading the request payload

  • Add below class RequestResponseMiddleware. This class is a middleware class with async method to invoke a middleware.
public class RequestResponseMiddleware
    {
        private readonly RequestDelegate _next;
        public RequestResponseMiddleware(RequestDelegate next)
        {
            _next = next;
        }
        public async Task Invoke(HttpContext context)
        {
            var originalBodyStream = context.Response.Body;
            context.Request.EnableRewind();
            try
            {
                //new MemoryStream. 
                using (var responseBody = new MemoryStream())
                {
                    // temporary response body 
                    context.Response.Body = responseBody;
                    //execute the Middleware pipeline 
                    await _next(context);
                    //read the response stream from the beginning
                    context.Response.Body.Seek(0, SeekOrigin.Begin);
                    //Copy the contents of the new memory stream
                    await responseBody.CopyToAsync(originalBodyStream);
                }
            }
            finally
            {
                context.Response.Body = originalBodyStream;
            }
        }
    }

Enable Middleware in API pipeline

  • Lets enable this middleware within pipeline by updating Startup.cs as below,

  • Controller methods GET and POST are simplified as below, Let’s add some payload using Order class to our GET and POST method as shown below,

blank

  • Model class Order for payload is defined as below,

public class Order
    {
        public string CustomerName { get;  set; }
        public string CustomerEmail { get;  set; }
        public int OrderId { get; set; }
        public string Address { get; set; }
    }

Using ResultFilter

  • Here I am making use of filters to log my request and response size by overriding OnResultExecuted() method. Please note that middleware in the pipeline will help us to read HTTP Context details which were not possible before by design.

blank

Using filters suffices the requirement for my case where I am able to log requests and response sizes to the logger.

One can also read requests and response within the middleware component if needed.

  • The result request and response size will be logged in the logger as shown below,
blank

Hope you liked this article. How can I help you further?

References

Do you have any comments or ideas or any better suggestions to share?

Please sound off your comments below.

Happy Coding !!



Please bookmark this page and share it with your friends. Please Subscribe to the blog to receive notifications on freshly published(2024) best practices and guidelines for software design and development.



2 thoughts on “Read Request and Response body in ASP.NET Core

Leave a Reply

Your email address will not be published. Required fields are marked *