简体   繁体   中英

Request body from is empty in .Net Core 3.0

Okay so I've been wracking my brain and cannot for the life of me understand why the exact same piece of code works perfectly in.Net Core 2.2 but returns an empty string in.Net Core 3.0.

The piece of code I am running is this:

public static async Task<string> GetRequestBodyAsync(this HttpRequest request,
                                                     Encoding encoding = null)
{
    if (encoding == null) encoding = Encoding.UTF8;
    var body = "";

    request.EnableBuffering();
    if (request.ContentLength == null || !(request.ContentLength > 0) || !request.Body.CanSeek) return body;

    request.Body.Seek(0, SeekOrigin.Begin);
    using (var reader = new StreamReader(request.Body, encoding, true, 1024, true))
        body = await reader.ReadToEndAsync();

    request.Body.Position = 0;
    return body;
}

And I call this extension as such:

var bodyContent = await Request.GetRequestBodyAsync();
var body = new MemoryStream(Encoding.UTF8.GetBytes(bodyContent));

In.Net Core 2.2 I get the body of the sent payload exactly as I want it, but in.Net Core 3.0 I get an empty string.

I am using the extension in my startup to add Newtonsoft to my project for.Net Core 3.0, but if I remove that it still doesn't work.

Any ideas what I might've done wrong?

Add this middleware in the startup class:

app.Use((context, next) =>
{
    context.Request.EnableBuffering();
    return next();
});

I actually figured it out, in the controller-method I read the body using [FromBody] so that the body was being read twice and not rewinded the first time.

public async Task<ActionResult<string>> PaymentRequestCallbackAsync(/*[FromBody] SecretModel model*/)
{
    var body = await Request.GetRequestBodyAsync();
    var stream = new MemoryStream(Encoding.UTF8.GetBytes(body));
    return body;
}

So remove the [FromBody] and it should work just fine.

Here is another solution which will help

write a middleware

public class EnableRequestBodyBufferingMiddleware
        {
            private readonly RequestDelegate _next;

            public EnableRequestBodyBufferingMiddleware(RequestDelegate next) =>
                _next = next;

            public async Task InvokeAsync(HttpContext context)
            {
                context.Request.EnableBuffering();

                await _next(context);
            }
        }

Then configure this middleware

app.UseMiddleware<EnableRequestBodyBufferingMiddleware>();

Now you can easily ready the body without any problem

        Request.EnableBuffering();
        Request.Body.Seek(0, SeekOrigin.Begin);
        using (StreamReader stream = new StreamReader(Request.Body))
        {
            string body = await stream.ReadToEndAsync();
        }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM