AspNet.Core returns 200 OK 无效 Json 如果迭代 IEnumerable 时出现异常(从控制器返回)

AspNet.Core returns 200 OK and invalid Json if there is an exception while iterating an IEnumerable (returned from controller)

似乎 AspNet.Core 立即开始发送 IEnumerable 的响应,而没有遍历整个集合。例如:

[HttpGet("")]
public async Task<IActionResult> GetData()
{
    IEnumerable<MyData> result = await _service.GetData();
    return Ok(result.Select(_mapper.MapMyDataToMyDataWeb));
}

现在在其中一个元素的映射过程中发生异常,所以我会假设一个 500 响应,但实际上发生的是我得到一个 200 只有部分(不正确)Json.

我认为它是 Asp.Net Core 中的一项功能而不是错误,它提供了这种行为,而且通过调用例如修复它也相对容易ToList(),但我想知道是否有某种标志可以防止这种情况发生,因为它实际上没有意义,例如API 项目和标准 JSON 响应。

我无法在描述此行为以及如何防止它的文档中找到任何内容。

P.S。我已经验证调用 ToList() 解决了问题并且响应是 500 正确的异常(UseDeveloperExceptionPage

似乎这实际上是 "by design",这个 issue 在 Asp.Net 核心 github 存储库中被提出了几次。

发生的情况是 header 和 200 已经发送,而 body 没有。虽然我认为枚举必须在发送 header 之前进行,但 asp.net 团队表示它将在服务器上使用更多资源,这就是为什么会这样。

引用一段话:

It is very likely the case that your exception is thrown while writing to the body, after headers have already been sent to the client, so there's no take-backs on the 200 that was already sent as part of the response. The client will see an error because the body will come back as incomplete.

If you want to deterministically report a 500 when this happens you'll need to either:

我可以确认此解决方案有效:

  1. 引用Microsoft.AspNetCore.Buffering
  2. app.UseMvc()前写app.UseResponseBuffering()