今天在排查 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了。