Search code examples
c#.netasp.net-core

How can I get the raw body content of a post or put request in the .net minimal API?


How can I get the raw body content of a post or put request in the .net minimal API?

I tried it like this:

app.MapPut($"/{controllerName}", async ([FromBody] BasisTypeDto dto, IRepository repo, HttpRequest request, HttpContext context) => {

    BuilderMinimalApiActionResult<object>.MakeActionResult(Crud.Update(dto, repo, host, DefaultElasticIndex)); }
)
    .AddEndpointFilter(async (efiContext, next) => {

        var s = efiContext.HttpContext.Features.Get<IHttpBodyControlFeature>();

        s.AllowSynchronousIO = true;
        var reader = new StreamReader(efiContext.HttpContext.Request.Body);

        var rawMessage = reader.ReadToEnd();
        return await next(efiContext);
    })

But in rawMessage I get an empty string, although the length of efiContext.HttpContext.Request.ContentLength == 112


Solution

  • The request body could be read only once. If you want to read multiple times, you should enable the buffering.

    More details, you could refer to below codes:

    app.Use(async (context, next) =>
    {
        context.Request.EnableBuffering(); // Allows request body to be read multiple times
        await next();
    });
    app.MapPut("/test", async ([FromBody] BasisTypeDto dto) =>
    {
     
        return new OkResult();
    }).AddEndpointFilter(async (efiContext, next) => {
    
        //var s = efiContext.HttpContext.Features.Get<IHttpBodyControlFeature>();
        efiContext.HttpContext.Request.Body.Position = 0;
        //s.AllowSynchronousIO = true;
        var reader = new StreamReader(efiContext.HttpContext.Request.Body);
    
        var rawMessage = reader.ReadToEnd();
        return await next(efiContext);
    });
    

    Result:

    enter image description here