asp.net-core - 读取请求正文两次

标签 asp.net-core asp.net-core-mvc asp.net-core-webapi

我正在尝试读取中间件中的主体以进行身份​​验证,但是当请求到达 api Controller 时,对象为空,因为主体已被读取。有没有办法解决。我正在我的中间件中读取这样的正文。

var buffer = new byte[ Convert.ToInt32( context.Request.ContentLength ) ];
await context.Request.Body.ReadAsync( buffer, 0, buffer.Length );
var body = Encoding.UTF8.GetString( buffer );

最佳答案

如果您使用 application/x-www-form-urlencodedmultipart/form-data ,您可以放心调用context.Request.ReadFormAsync()多次,因为它在后续调用中返回一个缓存的实例。

如果您使用不同的内容类型,则必须手动缓冲请求并将请求正文替换为可回绕的流,如 MemoryStream .以下是使用内联中间件的方法(您需要尽快在管道中注册它):

app.Use(next => async context =>
{
    // Keep the original stream in a separate
    // variable to restore it later if necessary.
    var stream = context.Request.Body;

    // Optimization: don't buffer the request if
    // there was no stream or if it is rewindable.
    if (stream == Stream.Null || stream.CanSeek)
    {
        await next(context);

        return;
    }

    try
    {
        using (var buffer = new MemoryStream())
        {
            // Copy the request stream to the memory stream.
            await stream.CopyToAsync(buffer);

            // Rewind the memory stream.
            buffer.Position = 0L;

            // Replace the request stream by the memory stream.
            context.Request.Body = buffer;

            // Invoke the rest of the pipeline.
            await next(context);
        }
    }

    finally
    {
        // Restore the original stream.
        context.Request.Body = stream;
    }
});

您也可以使用 BufferingHelper.EnableRewind()扩展名,它是 Microsoft.AspNet.Http 的一部分包:它基于类似的方法,但依赖于一个特殊的流,该流开始在内存中缓冲数据,并在达到阈值时将所有内容假脱机到磁盘上的临时文件:

app.Use(next => context =>
{
    context.Request.EnableRewind();

    return next(context);
});

仅供引用: future 可能会在 vNext 中添加缓冲中间件。

关于asp.net-core - 读取请求正文两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31389781/

相关文章:

asp.net-web-api - 如何在.net web api中将DateTime对象作为json传递

c# - Razor 没有将我的 "selected"值写入页面

c# - ASP.Net MVC 5 中的 Cookie

c# - 如何在 ASP.net Core 中实现 dataTables 服务器端分页/搜索/排序

caching - Asp.Net Core 中全局变量的替代方法?

c# - 为什么我的 Razor 'RenderSection' 没有被孙 View 继承?

c# - ASP.NET Core MVC 本地化警告 : AcceptLanguageHeaderRequestCultureProvider returned the following unsupported cultures

c# - 找不到 Visual Studio 2015 上的 ASP.NET 5 addMvc 方法

c# - 在 asp.net core 3.1 web api 中,分组和版本控制不能很好地协同工作

.net - 使用 .Net Core Web Api 中的 Azure B2C 处理密码重置