【问题标题】:Binding the raw request body in .net core without reading the request stream在.net核心中绑定原始请求体而不读取请求流
【发布时间】:2020-07-24 19:35:21
【问题描述】:

我们的一个客户坚持将原始请求正文发送到我们的 API(不是 json 或 xml),并且由于 .net 核心默认不支持它,我使用了与以下类似的想法:

[HttpPost]
[Route("example/{path}")]
public async Task<string> ReadStringDataManual(string path)
{
    using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
    {  
        return await reader.ReadToEndAsync();
    }
}

但是,在生产中,我们意识到 API 在加载时会引发以下异常。

System.Runtime.CompilerServices.TaskAwaiter:UnsafeOnCompletedInternal (method time = 1 ms, total time = 1 ms)
undefined(2011ms): await continuation

我不确定它是否与 Kestrel 相关,但我相信这是因为广泛的 I/O 操作。我还尝试了一种天真的方法——在方法签名中添加一个带有[FromBody] 属性的参数,但没有运气。

是否有任何其他选项可以在不使用流阅读器的情况下读取原始请求正文?

谢谢。

【问题讨论】:

标签: c# .net asp.net-core asp.net-web-api .net-core


【解决方案1】:

.NetCore 中读取请求的正文有点不同

[HttpPost]
[Route("example/{path}")]
public async Task<string> ReadStringDataManual(string path)
{

    ReadResult requestBodyInBytes = await Request.BodyReader.ReadAsync();
    Request.BodyReader.AdvanceTo(requestBodyInBytes.Buffer.Start, requestBodyInBytes.Buffer.End);
    string body = Encoding.UTF8.GetString(requestBodyInBytes.Buffer.FirstSpan);

    //Rest of the code

    return body;
}

【讨论】:

  • 感谢您的回复。我刚刚有机会尝试它,它工作正常,但是Microsoft.AspNetCore.Connections.ConnectionAbortedException: The connection was aborted by the application. ---&gt; System.InvalidOperationException: Reading is already in progress. 被抛出。我还在Request.BodyReader 上尝试过CancelPendingRead()Complete() 方法,但没有运气。你有什么想法吗?
  • 在这里发现问题github.com/dotnet/aspnetcore/issues/17840,如果在返回结果前加上Request.BodyReader.AdvanceTo(test.Buffer.Start, test.Buffer.End);,不会抛出异常。请将其添加到您的答案中
  • @skynyrd 你能看看你的意思吗?
猜你喜欢
  • 1970-01-01
  • 2020-03-23
  • 2022-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多