ASP.NET Core: протоколировать все запросы (чтение тела дважды) EnableRewind не работает для атрибута [FromBody] - PullRequest
0 голосов
/ 22 октября 2018

Я следую этому сообщению , как регистрировать все запросы.

Но этот код:

public async Task Invoke(HttpContext context)
{
    await this.LogRequest(context.Request);

    await this._next(context);
}

private async Task LogRequest(HttpRequest request)
{
    var body = request.Body;
    request.EnableRewind();

    var buffer = new byte[Convert.ToInt32(request.ContentLength)];
    await request.Body.ReadAsync(buffer, 0, buffer.Length);
    request.Body.Seek(0, SeekOrigin.Begin);
    var bodyAsText = Encoding.UTF8.GetString(buffer);
    request.Body = body;
}

не работает, потому что я получаю

"A non-empty request body is required."

в контроллере с атрибутом [ApiController]

[HttpPut("MyMethod")]
public async Task<ActionResult<MyModel>> MyMethod([FromBody]MyArgs model)
{
    //...
}

Я пытаюсь делать все виды комбинаций

    string bodyAsText = null;
    if (request.ContentLength > 0)
    {
        var body = request.Body;
        request.EnableRewind();

        using (var streamReader = new StreamReader(request.Body, Encoding.UTF8))
        {
            bodyAsText = await streamReader.ReadToEndAsync();
            request.Body.Seek(0, SeekOrigin.Begin);
        }
        request.Body = body;
    }

, но ничего не работает.Что мне здесь не хватает?Есть ответ с аналогичным решением на SO , но я не понимаю, почему он не работает в моем случае.

Если я комментирую код для чтения тела, он работает.

1 Ответ

0 голосов
/ 23 октября 2018

Я ждал, когда Ценг отправит ответ, так как он уже указал мне на проблему и решение в комментарии.Но так как он этого не сделал, я постараюсь ответить, основываясь на комментариях и опыте отладки.

Как упомянуто упоминание Ценга EnableRewind, надо var body = request.Body;

Этот код:

if (request.ContentLength > 0)
{
    request.EnableRewind();
    var body = request.Body;

    using (var streamReader = new StreamReader(request.Body, Encoding.UTF8))
    {
         bodyAsText = await streamReader.ReadToEndAsync();
         request.Body.Seek(0, SeekOrigin.Begin);
    }
    request.Body = body;
}

выдает ошибку:

Невозможно получить доступ к удаленному объекту.Имя объекта: 'FileBufferingReadStream'.

в строке await this._next(context);.

Рабочий код:

if (request.ContentLength > 0)
{
    request.EnableRewind();
    var body = request.Body;

    var buffer = new byte[Convert.ToInt32(request.ContentLength)];
    await request.Body.ReadAsync(buffer, 0, buffer.Length);
    request.Body.Seek(0, SeekOrigin.Begin);
    bodyAsText = Encoding.UTF8.GetString(buffer);
    request.Body = body;
}

Спасибо @Цзэн.

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