读取请求正文两次 [英] Read request body twice

查看:85
本文介绍了读取请求正文两次的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图出于身份验证目的在中间件中读取主体,但是当请求到达api控制器时,该对象为空,因为主体已被读取.有没有办法解决.我正在中间件中读取这样的身体.

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(),因为它会在后续调用中返回一个缓存的实例./p>

如果您使用其他内容类型,则必须手动缓冲请求,并用可倒带的流(如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);
});
 

仅供参考:将来可能会将缓冲中间件添加到vNext中.

I am trying to read the body in a middleware for authentication purposes, but when the request gets to the api controller the object is empty as the body has already been read. Is there anyway around this. I am reading the body like this in my middleware.

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

解决方案

If you're using application/x-www-form-urlencoded or multipart/form-data, you can safely call context.Request.ReadFormAsync() multiple times as it returns a cached instance on subsequent calls.

If you're using a different content type, you'll have to manually buffer the request and replace the request body by a rewindable stream like MemoryStream. Here's how you could do using an inline middleware (you need to register it soon in your pipeline):

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;
    }
});

You can also use the BufferingHelper.EnableRewind() extension, which is part of the Microsoft.AspNet.Http package: it's based on a similar approach but relies on a special stream that starts buffering data in memory and spools everything to a temp file on disk when the threshold is reached:

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

    return next(context);
});

FYI: a buffering middleware will probably be added to vNext in the future.

这篇关于读取请求正文两次的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆