Промежуточное ПО ядра .Net httpContext одновременное чтение и запись не поддерживается - PullRequest
0 голосов
/ 25 сентября 2019

Я добавил промежуточное ПО в ядре .Net, которое регистрирует каждый запрос API и ответ на nLog.У меня работает нормально, даже не заметил никаких проблем с ним.Сегодня я пытался сделать массовый запрос к API и получил исключение

. Одновременное чтение или запись не поддерживаются на await HttpContext.Request.Body.ReadAsync(buffer,0,buffer.Length), где буфер равен var buffer= new byte[Convert.ToInt32(HttpContext.Request.ContentLength)]

У меня есть некоторая путаница на этом уровне

  1. . Ядро .Net создает отдельный конвейер для каждого запроса.Я думаю, что да, поскольку HttpContext.Items уникальны для каждого цикла запроса.
  2. Если да, то почему я получаю параллельную ошибку.Как мой код, сначала зарегистрируйте запрос, затем передайте контекст следующему промежуточному программному обеспечению и, наконец, зарегистрируйте ответ.(Я что-то упускаю?)

Пожалуйста, если вы можете поделиться лучшим способом преодоления этой проблемы.

Вот код для справки

 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");
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...