ASP.NET Core:记录所有请求(两次读取正文)EnableRewind对[FromBody]属性不起作用

时间:2018-10-22 14:37:22

标签: asp.net asp.net-core asp.net-core-2.1

我正在跟踪this post如何记录所有请求。

但是此代码:

(name_of_env) vagrant@ubuntu-xenial:/vagrant/$ pip freeze > requirements.txt

不起作用,因为我知道

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)
{
    //...
}

但没有任何效果。我在这里想念什么?在SO上有类似解决方案的一些答案,但我不明白为什么在我的情况下它不起作用。

如果我注释阅读正文的代码,它会起作用。

1 个答案:

答案 0 :(得分:1)

我一直在等待Tseng发布答案,因为他已经指出我的问题和解决方案。但是由于他没有这么做,我将尝试根据注释和调试经验来回答。

曾梵志提到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;
}

谢谢@Tseng。