我正在尝试读取中间件中的主体以进行身份验证,但是当请求到达 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-urlencoded
或 multipart/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/