抛出异常的IEnumerable在传递到ASP.NET Core Web API中的OkResult时返回无效Json



在Visual Studio中启动一个新的ASP.NET Core Web API项目。

现在将ValuesController.Get((操作更改为:

// GET api/values
[HttpGet]
public ActionResult<IEnumerable<string>> Get()
{
var results = new[] {"hi"}.Select<string, string>(x => throw new ArgumentException());
return Ok(results);
}

当你点击此按钮时,你会得到200的响应,响应体只有[

现在,如果您现在将其更改为在传递到Ok((之前枚举错误Select,它将正确地引发一个错误,并返回500,其中包含默认ASP.NET API模板中预期的错误详细信息:

var results = new[] {"hi"}.Select<string, string>(x => throw new ArgumentException());
results.ToList();
return Ok(results);

这里发生了什么?

在第一个示例中,在JSON序列化开始之前,状态代码和响应头被发送到客户端。给JSON序列化程序一个IEnumerable<string>会导致延迟创建集合,最终在序列化过程中执行。这意味着在抛出异常之前发送200个状态代码和响应标头。因为状态代码已经发送,所以不能从200更改。响应也不能"撤消"——它是一个仅向前的数据流。

在第二个示例中,集合是在JSON序列化进程运行之前创建的。在这种情况下,在可以到达对return Ok(results)的调用之前抛出异常。无论您用于全局异常处理的是什么,都会捕获此异常并写出一个状态代码为500的响应。

最新更新