ASP.NET Core中的Ok(null)vs NoContent()-哪个更有效? [英] Ok(null) vs NoContent() in ASP.NET Core - which is more efficient?

查看:114
本文介绍了ASP.NET Core中的Ok(null)vs NoContent()-哪个更有效?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

两者最终都会产生空的204状态响应,但是哪个更快?

Both end up producing an empty 204 status response, but which one is faster?

很显然,如果您遵循DRY准则,写起来会干净得多

Obviously if you follow the DRY guidelines, it's much cleaner to write

return Ok(something);

而不是

if (something == null)
{
    return NoContent()
}
else
{
    return Ok(something);
}

检查源代码后, NoContent()转换为调用 StatusCode(204),就像 Ok(null)一样深入研究以查看他们到底在哪里检查(如果有的话)是否为空值,如果为空,则决定返回一个StatusCode 204(或以其他方式处理它).

After checking the source, NoContent() translates to calling StatusCode(204), as for Ok(null) I didn't dive deep enough to see where exactly they check (if at all they do) for a null value, and if it's null, decide to return a StatusCode 204 (or handle it some other way).

我个人认为 NoContent()会产生更快的性能,即使我们要谈论的差异只有几分之一秒.

I personally think that NoContent() will yield faster performance, even though the difference we'll be talking about is in the fractions of a second.

推荐答案

当您调用 return NoContent()时,它将返回 StatusCodeResult

When you call return NoContent(), it returns the StatusCodeResult NoContentResult.

要执行 StatusCodeResult 时,它所做的只是

When a StatusCodeResult is to be executed, all it does is setting the status code on the response:

public override void ExecuteResult(ActionContext context)
{
    // snip boilerplate code

    context.HttpContext.Response.StatusCode = StatusCode;
}

现在,当您调用 return Ok(something)时,实际上返回的是 OkObjectResult(something).顾名思义, OkObjectResult

Now when you call return Ok(something), what actually gets returned is an OkObjectResult(something). And as its name implies, an OkObjectResult is an ObjectResult.

有很多方法可以将对象结果写入输出,这就是MVC的内部作用所在.

And there are many, many ways an object result can be written to the output, and that's where MVC's internals kick in.

要执行响应时,对于 ObjectResult

When the response is to be executed, in the case of the ObjectResult, the registered IActionResultExecutor<ObjectResult> is resolved and ExecuteAsync() is called.

使用默认的MVC注册时,这是 <代码>ExecuteAsync() 将其格式化程序选择(即用于将提供的ObjectResult实际写入到网络中的已注册格式化程序中的一部分)卸载到恰当命名的 OutputFormatterSelector 在其构造函数中.

When using the default MVC registrations, this is the ObjectResultExecutor. Its ExecuteAsync() offloads its formatter selection (i.e. which of the registered formatters to use for actually writing the provided ObjectResult onto the wire) to the aptly named OutputFormatterSelector which it gets injected in its constructor.

当然,默认情况下,这就是

And of course, by default, that is the DefaultOutputFormatterSelector. Now this class pulls its output formatters from MvcOptions.OutputFormatters, which in the default configuration contains:

  • HttpNoContentOutputFormatter
  • StringOutputFormatter
  • StreamOutputFormatter
  • SystemTextJsonOutputFormatter

按此顺序.现在,对于实际选择(忽略内容协商代码,因为此处没有内容),选择器将遍历已注册的格式化程序,并选择第一个

In that order. Now for the actual selection (ignoring the content negotiation code, as there is no content here), the selector iterates over the registered formatters and chooses the first one that returns true for CanWriteResult(). And if the HttpNoContentOutputFormatter is set to TreatNullValueAsNoContent, which it is by default, and the Object to return is null, then it does return just that.

然后运行更多代码,最后在该格式化程序

Then some more code runs, and finally WriteAsync() is called on that formatter, doing this:

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;
}

是的,还有更多的代码可以运行.但是,实际上是否值得注意,应该由您进行基准测试.

So yeah, a lot more code runs. But whether that's actually noticeable, should be benchmarked by you.

现在,您是否实际上想要 Ok(null)返回204而不是200,这是

Now whether you actually want Ok(null) to return a 204 instead of a 200 is up for debate; you can opt out of it using this code in your startup:

services.AddMvc(options => 
{
    var noContentFormatter = options.OutputFormatters.OfType<HttpNoContentOutputFormatter>().FirstOrDefault();
    if (noContentFormatter != null)
    {
        noContentFormatter.TreatNullValueAsNoContent = false;
    }
});

这篇关于ASP.NET Core中的Ok(null)vs NoContent()-哪个更有效?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆