Я добавил промежуточное ПО в ядре .Net, которое регистрирует каждый запрос API и ответ на nLog.У меня работает нормально, даже не заметил никаких проблем с ним.Сегодня я пытался сделать массовый запрос к API и получил исключение
. Одновременное чтение или запись не поддерживаются на await HttpContext.Request.Body.ReadAsync(buffer,0,buffer.Length)
, где буфер равен var buffer= new byte[Convert.ToInt32(HttpContext.Request.ContentLength)]
У меня есть некоторая путаница на этом уровне
- . Ядро .Net создает отдельный конвейер для каждого запроса.Я думаю, что да, поскольку HttpContext.Items уникальны для каждого цикла запроса.
- Если да, то почему я получаю параллельную ошибку.Как мой код, сначала зарегистрируйте запрос, затем передайте контекст следующему промежуточному программному обеспечению и, наконец, зарегистрируйте ответ.(Я что-то упускаю?)
Пожалуйста, если вы можете поделиться лучшим способом преодоления этой проблемы.
Вот код для справки
public class LoggingMiddleware
{
readonly ILogger logger;
readonly RequestDelegate next;
public LoggingMiddleware(RequestDelegate next, ILogger<LoggingMiddleware> logger)
{
this.logger = logger;
this.next = next;
}
public async Task Invoke(HttpContext context)
{
LogRequest(context);
var originalBodyStream = context.Response.Body;
using (var responseBody = new MemoryStream())
{
context.Response.Body = responseBody;
await next(context).ConfigureAwait(false);
LogResponse(context);
await responseBody.CopyToAsync(originalBodyStream).ConfigureAwait(false);
}
}
private async void LogRequest(HttpContext context)
{
var request = context.Request;
request.EnableRewind();
var buffer = new byte[Convert.ToInt32(request.ContentLength)];
await request.Body.ReadAsync(buffer, 0, buffer.Length);
string requestBody = Encoding.UTF8.GetString(buffer);
request.Body.Seek(0, SeekOrigin.Begin);
context.Items["Request"] = requestBody; //Request is being used in Nlog config
logger.LogInformation("Request received ......"); // Some information
context.Items.Remove("Request");
}
private async void LogResponse(HttpContext context)
{
var response = context.Response;
response.Body.Seek(0, SeekOrigin.Begin);
var responseText = await new StreamReader(response.Body).ReadToEndAsync().ConfigureAwait(false);
response.Body.Seek(0, SeekOrigin.Begin);
context.Items["Response"] = responseText;
logger.LogInformation("Returned response for url with status"); // Information
context.Items.Remove("Response");
}
}