使用 System.Text.Json 时,MVC 不缓冲 IAsyncEnumerable 类型

在 ASP.NET Core 5 中,MVC 通过在内存中缓冲序列并格式化缓冲集合,添加了对输出格式设置 IAsyncEnumerable<T> 类型的支持。 在 ASP.NET Core 6 中,使用 System.Text.Json 进行格式化时,MVC 不再缓冲 IAsyncEnumerable<T> 实例。 相反,MVC 依赖于 System.Text.Json 为这些类型添加的支持。

在大多数情况下,应用程序无法观察到没有缓冲的情况。 但是,某些方案可能会无意中依赖缓冲语义来实现正确序列化。 例如,在具有延迟加载属性的类型上返回由实体框架查询支持的 IAsyncEnumerable<T> 可能会导致并发查询执行,提供程序可能不支持这种情况。

此更改不会影响使用 Newtonsoft.Json 或基于 XML 的格式化程序的输出格式设置。

引入的版本

ASP.NET Core 6.0

旧行为

对于从 MVC 操作返回,作为要使用 ObjectResultJsonResult 进行格式化的值的 IAsyncEnumerable<T> 实例,系统会在将其序列化为同步集合之前进行缓冲。

新行为

使用 System.Text.Json 进行格式化时,MVC 不再缓冲 IAsyncEnumerable<T> 实例。

更改原因

System.Text.Json 支持流式处理 IAsyncEnumerable<T> 类型。 这样可以在序列化过程中减少内存占用。

如果应用程序需要缓冲,请考虑手动缓冲 IAsyncEnumerable<T> 对象:

// Before
public IActionResult Get()
{
    return Ok(dbContext.Blogs);
}

// After
public async Task<IActionResult> Get()
{
    return Ok(await dbContext.Blogs.ToListAsync());
}