7

I have an error logger that writes errors from an API controller to the database. It has some code like this:

string form = string.Empty;
if (request.Method == "POST")
{
    using (StreamReader sr = new StreamReader(request.Body))
    {
        if (request.Body.CanSeek) request.Body.Seek(0, SeekOrigin.Begin);
        if (request.Body.CanRead) form = sr.ReadToEndAsync().Result;
        form = sr.ReadToEndAsync().Result;
    }
}

However, this can't read the body because it's already been read, and ASP.NET Core doesn't let you do this. See: https://devblogs.microsoft.com/aspnet/re-reading-asp-net-core-request-bodies-with-enablebuffering/

I looked at .EnableBuffering and .EnableRewind but neither of these exist on HttpRequest (at least not in 3.0.

app.Use(async (context, next) => {
    context.Request.EnableRewind();
    await next();
});

How do I get to reread the request body?

Sean
  • 14,359
  • 13
  • 74
  • 124

1 Answers1

17

EnableBuffering exists in dotnet 3.0, just add

using Microsoft.AspNetCore.Http;

then

app.Use(async (context, next) => {
    context.Request.EnableBuffering();
    await next();
});
Roman Marusyk
  • 23,328
  • 24
  • 73
  • 116
  • 1
    But at what point in configuring the pipeline should that function be added? Before .UseRouting()? Before .UseAuthentication()? After? – Nate Kennedy Apr 05 '21 at 20:53
  • Thanks Roman. i have put it before urlrouting. if it is wrong then please let me know where exact to place – Kamran Shahid Jun 14 '21 at 13:27
  • I think it depends if we want to re-read request body only for error logger then adding it before Routing or MapController method would do. If we are having the RequestLogging etc. then probably we should use the EnableBuffering in that middleware. Important thing is whenever stream is read after EnableBuffering() is called.. stream has to move back to Position 0 So that other middleware down the line could re-read the request body again. for ex. context.Request.Body.Position = 0; – GPuri Sep 16 '22 at 13:26