Прочитайте первые n символов HttpContent
Я хочу регистрировать информацию об ответах HttpRequestMessage в программе Visual C# Web API. Я хочу использовать обработчик сообщений (наследование от DelegatingHandler), как это:
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
// log request.Method & request.RequestUri
var result = await base.SendAsync(request, cancellationToken);
// log first 100 chars of result.Content
return result
}
Проблема в том, что result.Content
иногда будет огромным, поэтому я хочу ограничить его печатью только первых N символов (примерно 50).
Что я пробовал:
- Копирование всего этого в строку с
toString()
и используяSubString
, Это именно то, что я хочу, но, кажется, расточительно читать огромные строки в памяти, а затем использовать только первые несколько символов - я чувствую, что должен быть лучший способ. - Различные решения со всего Интернета, которые читают символы, но удаляют их из потока. Мне нужно отправить полный поток обратно как есть.
1 ответ
При этом вы можете скопировать необходимую информацию из потока и передать ответ туда, куда он идет.
protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken) {
// log request.Method & request.RequestUri
var response = await base.SendAsync(request, cancellationToken);
// log first 100 chars of response.Content
var N = 100;
var first_100_Chars = await ReadFirstNCharsOfHttpContent(response.Content, N);
return response;
}
private static async Task<string> ReadFirstNCharsOfHttpContent(HttpContent httpContent, int N = 100) {
//get the content Stream
var contentStream = await httpContent.ReadAsStreamAsync().ConfigureAwait(false);
//How big is it
var streamLength = contentStream.Length;
// Get the size of the buffer to be read
var bufferSize = (int)(streamLength > N ? N : (N > streamLength ? streamLength : N));
var ms = new System.IO.MemoryStream(bufferSize);
//copy only the needed length
await contentStream.CopyToAsync(ms, bufferSize);
// The StreamReader will read from the current
// position of the MemoryStream which is currently
// set at the end of the data we just copied to it.
// We need to set the position to 0 in order to read
// from the beginning.
ms.Position = 0;
//reset content position just to be safe.
contentStream.Position = 0;
var sr = new System.IO.StreamReader(ms);
var logString = sr.ReadToEnd();
return logString;
}