今天在排查 web api 问题时需要输出 request body 的内容看一下,之前都是通使用 Request.Body ,今天想试试 Request.BodyReader,它的类型是 PipeReader,请问如何使用 System.IO.Pipelines.PipeReader 读取内容输出到字符串?
通过 Binding the raw request body in .net core without reading the request stream 回答中的现成代码解决了
Request.Body.Position = 0;
var readResult = await Request.BodyReader.ReadAsync();
Request.BodyReader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End);
string body = Encoding.UTF8.GetString(readResult.Buffer.FirstSpan);
需要注意的是,如果在 Controller Action 中读取,由于 Model Binding 的抢先一步读掉了 request body 中的数据,后续就读不到数据,需要添加下面的 middleware 启用 EnableBuffering,详见 Reading the raw request body as a string in ASP.NET Core
app.Use(next => context =>
{
context.Request.EnableBuffering();
return next(context);
});
注:这个 middleware 放在 app.UseRouting() 之前
Request.Body.Position = 0 也是因为 Model Binding 已经读过 request body,需要重置 Position
大佬非常牛逼。最近做海康的ISAPI的集成发现之前的方法是搞不定的,方法如下:
//StreamReader sr = new StreamReader(request.Body);
//string bodyContent1 = sr.ReadToEnd();
//string bodyContent = sr.ReadToEndAsync().GetAwaiter().GetResult();
//request.Body.Seek(0, SeekOrigin.Begin);
之前的方式可以兼容axios,还有postman,但是海康过来的数据都直接报错:
Unexpected end of request content
用了大佬的方法,就全部OK了。