gpt4 book ai didi

c# - 如何重置 PipeReader 以便能够在 ASP.NET Core 中重新读取请求正文

转载 作者:行者123 更新时间:2023-12-03 19:17:07 26 4
gpt4 key购买 nike

我有一些 ASP.NET Core 中间件(一个 AuthorizationHandler )需要访问请求的主体以执行授权检查。我使用新的 pipelines APIs 访问请求正文。代码如下所示:

PipeReader bodyReader = httpContext.Request.BodyReader;

ReadResult readResult = await bodyReader.ReadAsync();
ReadOnlySequence<byte> readResultBuffer = readResult.Buffer;

var utf8JsonReader = new Utf8JsonReader(bytes);
while (utf8JsonReader.Read()) { ... }

运行此代码后,将读取正文流。我要调用的 Controller 抛出验证错误,因为它没有看到请求正文,因为它已被读取。

那么如何重置 PipeReader 以便可以重新读取请求正文?

我知道当您不使用 BodyReader 而是 Body 时,您可以使用 EnableBuffering 来启用请求重新读取。但是,当使用管道时,这不再有效(或者我做错了其他事情)。

最佳答案

我昨天创建了一个问题。见 jkotalik's comment :

By passing in readResult.Buffer.Start for consumed, you are saying that you haven't consumed any of the ReadResult. By passing in readResult.Buffer.End, you are saying you have examined everything, which tells the Pipe to not free any buffers and the next time ReadAsync returns, more data would be in the buffer



这激励我调用 bodyReader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.Start); 来重置检查的位置。

例如,您的中间件可以写成如下:

异步任务 IMiddleware.InvokeAsync(HttpContext httpContext, RequestDelegate next)
{
if(httpContext.Request.Method != HttpMethods.Post){
返回;
}
var bodyReader = httpContext.Request.BodyReader;//不要通过`PipeReader.Create(httpContext.Request.Body);`获取它

//演示:读取所有主体而不消耗它
读取结果读取结果;
而(真){
readResult = await bodyReader.ReadAsync();
if(readResult.IsCompleted) { 中断; }
//不要消费它们,而是检查它们
bodyReader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
}
//现在所有的 body 负载都已读入缓冲区
var buffer = readResult.Buffer;
进程(引用缓冲区);//处理有效载荷 (ReadOnlySequence)

//最后,在这里重置 EXAMINED POSITION
bodyReader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.Start);
等待下一个(httpContext);
}

无效过程(引用 ReadOnlySequence 缓冲区){
var utf8JsonReader = new Utf8JsonReader(buffer);
而 (utf8JsonReader.Read()) {
Console.WriteLine($"{utf8JsonReader.TokenType}");
...
}
}

(关键是 AdvanceTo()不仅可以转发消耗的位置,还可以改变被检查的位置)

关于c# - 如何重置 PipeReader 以便能够在 ASP.NET Core 中重新读取请求正文,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60269628/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com