.NET Framework 4.8中ASP.NET Web API如何流式传输JSON数据?
在.NET Framework 4.8的ASP.NET Web API中实现JSON数组流式传输
由于.NET Framework 4.8不支持IAsyncEnumerable,你可以使用PushStreamContent来实现JSON数组的流式传输,它允许你直接操控响应流,分批次写入数据,达到和.NET Core中类似的实时输出效果。
核心实现思路
通过PushStreamContent接管响应流的写入逻辑:
- 手动构建JSON数组的结构(先写
[,逐个写入元素并添加分隔符,最后写]) - 每次写入元素后立即刷新流,确保数据实时发送到客户端
- 禁用响应缓存,避免数据被中间节点缓冲
完整代码示例
using Newtonsoft.Json; using System.IO; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Threading.Tasks; using System.Web.Http; public class StreamController : ApiController { public HttpResponseMessage Get() { var response = new HttpResponseMessage(HttpStatusCode.OK); // 初始化PushStreamContent,传入异步写入逻辑 response.Content = new PushStreamContent(async (stream, content, context) => { using var writer = new StreamWriter(stream, Encoding.UTF8); // 写入JSON数组开头 await writer.WriteAsync("["); await writer.FlushAsync(); // 输出第一个元素 var firstItem = JsonConvert.SerializeObject("test"); await writer.WriteAsync(firstItem); await writer.FlushAsync(); // 每秒输出一个后续元素 for (int i = 0; i < 3; i++) { await Task.Delay(1000); // 先写逗号分隔符 await writer.WriteAsync(","); var item = JsonConvert.SerializeObject($"Test {i}"); await writer.WriteAsync(item); await writer.FlushAsync(); } // 写入JSON数组结尾 await writer.WriteAsync("]"); await writer.FlushAsync(); }); // 设置响应内容类型为JSON response.Content.Headers.ContentType = new MediaTypeHeaderValue("application/json"); // 禁用缓存,确保实时传输 response.Headers.CacheControl = new CacheControlHeaderValue { NoCache = true }; return response; } }
关键细节说明
- 流刷新:每次写入后调用
FlushAsync()是关键,它会把缓冲区的数据立即发送到客户端,避免等待缓冲区填满才输出。 - JSON结构维护:因为是流式输出,需要手动维护JSON数组的语法正确性,确保元素之间用逗号分隔,首尾的
[]正确闭合。 - 复杂对象支持:如果需要传输复杂对象,只需将
JsonConvert.SerializeObject的参数替换为你的实体对象即可,序列化逻辑和常规Web API一致。
测试验证
使用curl -N http://你的API地址/api/stream请求接口,终端会每秒输出一段JSON内容,最终拼接成完整的数组,效果和你在.NET Core中实现的完全一致。
内容的提问来源于stack exchange,提问作者Lance
相关产品推荐
相关产品推荐

