阅读身体Asp.Net两次5 [英] Read body twice in Asp.Net 5

查看:215
本文介绍了阅读身体Asp.Net两次5的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图读取身体用于认证目的中间件,但是当请求获取到API控制器作为主体已经读出的对象是空的。反正是有解决这个问题。我读的身体像这样在我的中间件。

  VAR缓冲=新的字节[Convert.ToInt32(context.Request.ContentLength)];
等待context.Request.Body.ReadAsync(缓冲液,0,buffer.Length);
变种体= Encoding.UTF8.GetString(缓冲液);


解决方案

如果你使用应用程序/ x-WWW的形式urlen codeD 的multipart / form-data的,你可以安全地调用 context.Request.ReadFormAsync()多次因为它返回一个缓存实例在随后的电话。

如果您使用的是不同的内容类型,您必须手动缓冲要求,并通过如的MemoryStream A rewindable的流更换请求主体。这里是你如何使用内联中间件(你需要在你的管道尽快注册吧)做的:

  app.Use(下一=>异步上下文= GT; {
    //保持原始流中的一个单独的
    //变量,如果需要在以后恢复它。
    VAR流= context.Request.Body;    //优化:没有缓冲,如果请求
    //没有流或者如果它是re​​windable的。
    如果(流== || Stream.Null stream.CanSeek){
        接下来的等待(背景);        返回;
    }    尝试{
        使用(VAR缓冲=新的MemoryStream()){
            //请求流复制到内存流。
            等待stream.CopyToAsync(缓冲);            //倒回内存流。
            buffer.Position = 0L;            //由内存流替换请求流。
            context.Request.Body =缓冲;            //调用管道的其余部分。
            接下来的等待(背景);
        }
    }    最后{
        //恢复原来的流。
        context.Request.Body =流;
    }
});

您也可以使用 BufferingHelper.EnableRewind()的扩展,这是 Microsoft.AspNet.Http 包:它是基于相似的方法,但是依赖于内存中缓冲开始的数据,并且达到阈值时线轴一切磁盘上的临时文件一种特殊的流:

  app.Use(下一=>背景= GT; {
    context.Request.EnableRewind();    返回下一个(上下文);
});

供参考:一个缓冲中间件可能会被加入到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.

这篇关于阅读身体Asp.Net两次5的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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