c# - ASP.NET Core 中的 Ok(null) 与 NoContent() 哪个更有效?
问题描述
两者最终都会产生一个空的 204 状态响应,但哪个更快?
显然,如果你遵循 DRY 指南,写起来会更干净
return Ok(something);
而不是
if (something == null)
{
return NoContent()
}
else
{
return Ok(something);
}
检查源代码后,NoContent()
转换为调用StatusCode(204)
,至于Ok(null)
我没有深入了解他们检查的确切位置(如果他们这样做)是否为空值,如果它为空,则决定返回一个 StatusCode 204(或处理它以其他方式)。
我个人认为这NoContent()
将产生更快的性能,即使我们将要谈论的差异只有几分之一秒。
解决方案
当您调用时return NoContent()
,它会返回StatusCodeResult
NoContentResult
.
当StatusCodeResult
要执行 a 时,它所做的只是在响应上设置状态代码:
public override void ExecuteResult(ActionContext context)
{
// snip boilerplate code
context.HttpContext.Response.StatusCode = StatusCode;
}
现在,当您调用时return Ok(something)
,实际返回的是一个OkObjectResult(something)
. 顾名思义, anOkObjectResult
是一个ObjectResult
.
并且有很多很多方法可以将对象结果写入输出,这就是 MVC 的内部机制发挥作用的地方。
当要执行响应时,在 的情况下ObjectResult
,注册IActionResultExecutor<ObjectResult>
的被解析并被ExecuteAsync()
调用。
使用默认 MVC 注册时,这是ObjectResultExecutor
. 它将其ExecuteAsync()
格式化程序选择(即使用哪个已注册格式化程序将提供的 ObjectResult 实际写入线路)卸载到OutputFormatterSelector
它在其构造函数中注入的恰当命名的格式化程序。
当然,默认情况下,这是DefaultOutputFormatterSelector
. 现在,此类从中提取其输出格式化程序,MvcOptions.OutputFormatters
默认配置中包含:
- HttpNoContentOutputFormatter
- 字符串输出格式化程序
- 流输出格式化程序
- SystemTextJsonOutputFormatter
以该顺序。现在对于实际的选择(忽略内容协商代码,因为这里没有内容),选择器遍历注册的格式化程序并选择第一个返回true
forCanWriteResult()
的格式化程序。如果HttpNoContentOutputFormatter
设置为TreatNullValueAsNoContent
(默认情况下),而要Object
返回的是null
,那么它确实会返回。
然后运行更多代码,最后WriteAsync()
在该格式化程序上调用,这样做:
public Task WriteAsync(OutputFormatterWriteContext context)
{
var response = context.HttpContext.Response;
response.ContentLength = 0;
if (response.StatusCode == StatusCodes.Status200OK)
{
response.StatusCode = StatusCodes.Status204NoContent;
}
return Task.CompletedTask;
}
所以,是的,更多的代码运行。但是,这是否真的很明显,应该由你来衡量。
现在,您是否真的要 Ok(null)
返回 204 而不是 200有待商榷;您可以在启动时使用以下代码选择退出:
services.AddMvc(options =>
{
var noContentFormatter = options.OutputFormatters.OfType<HttpNoContentOutputFormatter>().FirstOrDefault();
if (noContentFormatter != null)
{
noContentFormatter.TreatNullValueAsNoContent = false;
}
});
推荐阅读
- javascript - 选择了哪个垫子菜单?
- sql - 具有字符串的数学运算的 SQL 数据类型
- json - 引号中的 Windows 命令类型关键字
- javascript - 有没有办法让一个只设置上下文而不在上下文更新时重新渲染的组件?反应
- html - 正文不断超过网页的全尺寸
- c# - 报表不是表格格式时如何将水晶报表数据以表格格式导出到excel
- asp-classic - 通过脚本发送电子邮件时的经典 ASP 错误
- mysql - 当前月份的运行总和,累计运行总计上限
- tsql - 批处理文件 - 缺少运算符
- database - 我必须在前端加载 scorm 包还是必须在后端解包并单独提供资产?