Одна вещь:
Очень важно отметить, что строка с закрывающим идентификатором Heredoc не должна содержать других символов, кроме точки с запятой (;). Это означает, что идентификатор не может быть отступом и не может быть никаких пробелов или вкладок до или после точки с запятой.
Пример:
$str = <<<EOD
Example of string
spanning multiple lines
using heredoc syntax.
EOD;
Просто найдено одно решение. Замена исходного потока новым потоком, содержащим данные.
public override Task Invoke(IOwinContext context)
{
return Task.Run(() => {
string body = new StreamReader(context.Request.Body).ReadToEnd();
// log body
byte[] requestData = Encoding.UTF8.GetBytes(body);
context.Request.Body = new MemoryStream(requestData);
this.Next.Invoke(context);
});
}
Если вы имеете дело с большими объемами данных, я уверен, что FileStream
также будет работать как замена.
Вот небольшое усовершенствование первого ответа от Despertar, которое мне очень помогло, но я столкнулся с проблемой при работе с двоичными данными. Промежуточный шаг извлечения потока в строку, а затем возврат его в массив байтов с использованием Encoding.UTF8.GetBytes(body)
испортил двоичный контент (содержимое изменится, если оно не является кодировкой UTF8). Вот мое исправление, использующее Stream.CopyTo()
:
public override async Task Invoke(IOwinContext context)
{
// read out body (wait for all bytes)
using (var streamCopy = new MemoryStream())
{
context.Request.Body.CopyTo(streamCopy);
streamCopy.Position = 0; // rewind
string body = new StreamReader(streamCopy).ReadToEnd();
// log body
streamCopy.Position = 0; // rewind again
context.Request.Body = streamCopy; // put back in place for downstream handlers
await this.Next.Invoke(context);
}
}
Кроме того, MemoryStream
приятно, потому что вы можете проверить длину потока до регистрации всего тела (чего я не хочу делать в случае кто-то загружает огромный файл).
Я знаю, что это старо, но только для того, чтобы помочь любому, кто сталкивается с этим. Вам нужно искать в потоке: context.Request.Body.Seek(0, SeekOrigin.Begin);