首页 > 解决方案 > 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()将产生更快的性能,即使我们将要谈论的差异只有几分之一秒。

标签: c#asp.net-coreoptimization

解决方案


当您调用时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

以该顺序。现在对于实际的选择(忽略内容协商代码,因为这里没有内容),选择器遍历注册的格式化程序并选择第一个返回trueforCanWriteResult()的格式化程序。如果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;
    }
});

推荐阅读