【问题标题】:How to send IAsyncEnumerator from WebAPI and stream data through HttpClient in C# 8+?如何在 C# 8+ 中从 WebAPI 发送 IAsyncEnumerator 并通过 HttpClient 流式传输数据?
【发布时间】:2019-10-07 03:47:48
【问题描述】:

Examples 用于使用内部服务将数据从 IAsyncEnumerator 读取到 Blazor 应用中的 UI。 Examples 还介绍了如何将 IAsyncEnumerator 作为 Web API 控制器操作的输出发送。

我还没有看到任何示例,如何在 Blazor 或 Xamarin 等客户端中使用 HttpClient 从 API 读取 IAsyncEnumerator 流。到目前为止,我尝试过的所有操作都只在 API 上的 async/await foreach 循环完成后返回客户端上的 HttpResponseMessage。

HttpResponseMessage response = await _httpClient.GetAsync(url, HttpCompletionOption.ResponseHeadersRead).ConfigureAwait(false);

HttpGet 操作的内容类型应该是什么(Produces 属性)?来自 HttpClient 的请求标头上的 Accept 值应该是什么?

[HttpGet]
[Produces("application/json")]
public async IAsyncEnumerable<Data> Get(CancellationToken cancellationToken)
{
    var dbSet = _dbContext.TableName.AsNoTracking().AsAsyncEnumerable().WithCancellation(cancellationToken).ConfigureAwait(false);
    await foreach (var i in dbSet.ConfigureAwait(false))
    {
        var item = new Data
        {
            Id = i.Id,
            Name = i.Name
        };
        yield return item;
    }
}

【问题讨论】:

  • 因此您需要 response.Content.ReadAsStreamAsync() 并反序列化流中的实体,例如 here。你的问题是什么?请提供完整的客户端代码。
  • Blazor 使用 SignalR 将更改流式传输到客户端。返回 IAsyncEnumerable 不会将操作转换为 SignalR 端点。 HTTP 响应根本没有改变。此外,JSON 和 XML 都返回整个文档,而不是部分结果 - 结果仍将作为 JSON 数组到达客户端
  • 如果您希望客户端处理流式传输结果,则必须使用 SignalR 或 gRPC 流式传输。两者都在 .NET Core 中可用,易于编写且速度快。

标签: c# dotnet-httpclient blazor c#-8.0 iasyncenumerable


【解决方案1】:

您最好不要使用原始 http 1.1 请求-响应模型,该模型不是为此而设计的,并且流对象与下载文件不同。 使用支持多路复用的websocket或http2.0,您可以将IAsyncEnumerable产生的每个元素序列化并在客户端进行反序列化。但这仍然是手动控制的,不值得。 您可以使用 ASP.NET Core 正式支持并支持对象流的 gRPC。与仅支持 JavaScript/.NET/Java 和的 SignalR 相比,它还支持更多语言并具有强类型接口定义。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-08
    • 2019-10-29
    • 2022-01-04
    • 2016-11-16
    • 1970-01-01
    • 1970-01-01
    • 2022-12-23
    • 1970-01-01
    相关资源
    最近更新 更多