如何在 .net core 中获取 HttpRequest 的请求体?

13

我想在.NET Core中获取HTTP请求正文,我使用了以下代码:

using (var reader
    = new StreamReader(req.Body, Encoding.UTF8))
{
    bodyStr = reader.ReadToEnd();
}
req.Body.Position = 0

但我遇到了这个错误:

System.ObjectDisposedException: 无法访问已释放的对象。 对象名称:“FileBufferingReadStream”。

在“using”语句后发生了错误

如何在 .net core 中获取 HttpRequest Body? 如何修复这个错误?


请参见我的回答下面的曾先生的评论(https://dev59.com/H6_la4cB1Zd3GeqPoig2#52850301)。[API](https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.http.internal.bufferinghelper.enablerewind?view=aspnetcore-2.1) - itminus
我仍然得到相同的错误。 - rayan periyera
可能是在过滤器中读取Response.Body流的重复问题 - Linda Lawton - DaImTo
请给我们一些更多的上下文,例如您在哪里使用这段代码?展示一些周围的代码。 - andynormancx
代码片段不会抛出异常。如果您能提供更多关于您的代码的细节,那将有助于我们理解您的问题。 - Ravikumar
4个回答

11

使用此扩展方法获取httpRequest Body:

   public static string GetRawBodyString(this HttpContext httpContext, Encoding encoding)
    {
        var body = "";
        if (httpContext.Request.ContentLength == null || !(httpContext.Request.ContentLength > 0) ||
            !httpContext.Request.Body.CanSeek) return body;
        httpContext.Request.EnableRewind();
        httpContext.Request.Body.Seek(0, SeekOrigin.Begin);
        using (var reader = new StreamReader(httpContext.Request.Body, encoding, true, 1024, true))
        {
            body = reader.ReadToEnd();
        }
        httpContext.Request.Body.Position = 0;
        return body;
    }

重要的是HttpRequest.Body是一个流类型,当StreamReader被处理时,HttpRequest.Body也会被处理。
在GitHub中找到以下链接,参考下面的链接和GetBody方法: https://github.com/devdigital/IdentityServer4TestServer/blob/3eaf72f9e1f7086b5cfacb5ecc8b1854ad3c496c/Source/IdentityServer4TestServer/Token/TokenCreationMiddleware.cs

很好,我之前也遇到过这个问题,后来找到了那个链接。 - amirhamini

2

简单解决方案:

using (var content = new StreamContent(Request.Body))
{
     var contentString = await content.ReadAsStringAsync();
}

1
请查看答案,由Stephen Wilkinson提供。
对于.NET Core 3.1,请使用以下内容。

Startup.cs

app.Use((context, next) =>
{
    context.Request.EnableBuffering(); // calls EnableRewind() `https://github.com/dotnet/aspnetcore/blob/4ef204e13b88c0734e0e94a1cc4c0ef05f40849e/src/Http/Http/src/Extensions/HttpRequestRewindExtensions.cs#L23`
    return next();
});

根据其他答案,您应该能够倒带:

httpContext.Request.Body.Seek(0, SeekOrigin.Begin);

0

我尝试了被接受的答案,但是它对我没有用,不过我读取了两次正文。

    public static string ReadRequestBody(this HttpRequest request, Encoding encoding)
    {
        var body = "";
        request.EnableRewind();

        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 = reader.ReadToEnd();
        }

        //Reset the stream so data is not lost
        request.Body.Position = 0;

        return body;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接