[SOLVED] Reading request body in middleware for .Net 5

Issue

I am trying to read the request body that was sent from client to my backend. The content is sent in JSON format and has users input from a form. How do I read the request body in a middleware that I set up for my controller Route.

Here is my Model

namespace ChatboxApi.Models
{
    public class User
    {
        public string Login { get; set; } = default;
        public string Password { get; set; } = default;
        public string Email { get; set; } = default;
        public string FullName { get; set; } = default;
        public int Phone { get; set; } = default;
        public string Website { get; set; } = default;

    }
}

Here is my Controller

namespace ChatboxApi.Controllers
{
    [ApiController]
    [Route("api/signup")]
    public class SignupController : ControllerBase
    {
        [HttpPost]
        public ActionResult SignUp([FromBody] User user)
        {
            return Ok(user);
        }

    }
}

Here is my middleware class

namespace ChatboxApi.Middleware
{
    public class CreateSession
    {
        private readonly RequestDelegate _next;

        public CreateSession(RequestDelegate next)
        {
            this._next = next;
        }

        public async Task Invoke(HttpContext httpContext)
        {
           //I want to get the request body here and if possible
           //map it to my user model and use the user model here.
            
            
        }

}

Solution

Usually Request.Body does not support rewinding, so it can only be read once. A temp workaround is to pull out the body right after the call to EnableBuffering and then rewinding the stream to 0 and not disposing it:

public class CreateSession
{
    private readonly RequestDelegate _next;

    public CreateSession(RequestDelegate next)
    {
        this._next = next;
    }

    public async Task Invoke(HttpContext httpContext)
    {
        var request = httpContext.Request;

        request.EnableBuffering();
        var buffer = new byte[Convert.ToInt32(request.ContentLength)];
        await request.Body.ReadAsync(buffer, 0, buffer.Length);
        //get body string here...
        var requestContent = Encoding.UTF8.GetString(buffer);

        request.Body.Position = 0;  //rewinding the stream to 0
        await _next(httpContext);

    }
}

Register the service:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    //...
    app.UseHttpsRedirection();

    app.UseMiddleware<CreateSession>();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });

}

Answered By – Rena

Answer Checked By – Mildred Charles (BugsFixing Admin)

Leave a Reply

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