我试图在ASP.NET Core控制器中以byte[]
数组的形式获取请求的正文。这是我最初写的:
var declaredLength = (int)request.ContentLength;
byte[] fileBuffer = new byte[declaredLength];
request.Body.Read(fileBuffer, 0, declaredLength);
此代码有效,但仅适用于较小的请求(约20KB)。对于较大的请求,它会填充数组中的前20,000个字节左右,然后数组的其余部分为空。
我在顶部的答案here中使用了一些代码,并且在重写代码后能够成功读取整个请求正文:
var declaredLength = (int)request.ContentLength;
byte[] fileBuffer = new byte[declaredLength];
// need to enable, otherwise Seek() fails
request.EnableRewind();
// using StreamReader apparently resolves the issue
using (var reader = new StreamReader(request.Body, Encoding.UTF8, true, 1024, true))
{
reader.ReadToEnd();
}
request.Body.Seek(0, SeekOrigin.Begin);
request.Body.Read(fileBuffer, 0, declaredLength);
为什么StreamReader.ReadToEnd()
无法成功读取整个请求正文,而Stream.Read()
无法读取?两次读取请求流感觉就像是黑客。有没有更好的方法来解决这个问题? (我只需要将流读入字节数组一次)
答案 0 :(得分:2)
请记住,您正在尝试阅读request.Body
,但尚未收到所有请求。
Stream.Read
的行为如下:
0
如您所见,如果尚未接收到整个身体,request.Body.Read(...)
只会返回已接收到的身体部分。
StreamReader.ReadToEnd()
调用Stream.Read
in a loop,直到找到流的结尾。
您可能还应该在循环中调用Stream.Read
,直到您读完所有字节为止:
byte[] fileBuffer = new byte[declaredLength];
int numBytesRead = 0;
while (numBytesRead < declaredLength)
{
int readBytes = request.Body.Read(fileBuffer, numBytesRead, declaredLength - numBytesRead);
if (readBytes == 0)
{
// We reached the end of the stream before we were expecting it
// Might want to throw an exception here?
}
numBytesRead += readBytes;
}