无法在 Task<IActionResult>、IActionResult 和 ActionResult<Thing> 之间做出决定

Don*_*ana 28 .net c# asp.net-web-api

虽然我明白的概念TaskActionResult等我仍然觉得这将是最直观的,如果没有指定任何其他在控制器输入不确定。

考虑到与返回的类型一样明确,我应该这样做:

[HttpGet] public ActionResult<Thing> Get()
{
  return Ok(Context.Things);
}
Run Code Online (Sandbox Code Playgroud)

但是,对于通用类型的 API 范例,我应该使用它:

[HttpGet] public IActionResult Get()
{
  return Ok(Context.Things);
}
Run Code Online (Sandbox Code Playgroud)

最后,尊重 API 哲学的异步性质,我应该应用以下内容:

[HttpGet] public Task<IActionResult> Get()
{
  return Ok(Context.Things);
}
Run Code Online (Sandbox Code Playgroud)

我无法决定在一般的绿地场景中哪个最合适。前两个似乎有效。直觉上,我更愿意使用第三个,但由于它不起作用(转换无效),我担心可能我在咆哮错误的二叉树。

完全不知道如何用谷歌搜索它,我正在获取各种示例。不确定如何判断哪些是相关的,我更愿意问。

Rac*_*lan 50

以下是不同退货选项的快速比较:

具体类型

public Thing Get() {
    return Context.Things.GetThing(1234);
}
Run Code Online (Sandbox Code Playgroud)

如果操作总是返回一种可能的类型,这是可以的。但是,大多数操作可能会返回具有不同类型的异常(即 200 以外的状态代码)。

IActionResult 类型

这解决了上述问题,因为IActionResult返回类型涵盖了不同的返回类型。

public IActionResult Get() {
    Thing thing = Context.Things.GetThing(1234);
    if (thing == null)
        return NotFound();
    else
        return Ok(thing);
}
Run Code Online (Sandbox Code Playgroud)

对于异步操作,请使用Task<IActionResult>

public async Task<IActionResult> Get() {
    Thing thing = await Context.Things.GetThing(1234);
    if (thing == null)
        return NotFound();
    else
        return Ok(thing);
}
Run Code Online (Sandbox Code Playgroud)

动作结果类型

ASP.NET Core 2.1 引入了ActionResult<T>返回类型,与类型相比,它具有以下优点IActionResult

1- 操作的预期返回类型是从Tin推断出来的ActionResult<T>。如果你用[ProducesResponseType]属性修饰你的动作,你就不再需要显式指定它的Type属性。例如,您可以简单地使用[ProducesResponseType(200)]代替[ProducesResponseType(200, Type = typeof(Thing))]

2-T转换为ObjectResult,这意味着return new ObjectResult(T);简化为return T;

public ActionResult<Thing> Get() {
    Thing thing = Context.Things.GetThing(1234);
    if (thing == null)
        return NotFound();
    else
        return thing;
}
Run Code Online (Sandbox Code Playgroud)

对于异步操作,请使用Task<ActionResult<T>>

public async Task<ActionResult<Thing>> Get() {
    Thing thing = await Context.Things.GetThing(1234);
    if (thing == null)
        return NotFound();
    else
        return thing;
}
Run Code Online (Sandbox Code Playgroud)

有关更多详细信息,您可以参考ASP.NET Core Web API 中的 MSDN 页面控制器操作返回类型

  • @TheShortestMustacheTheorem 我删除了 `Ok()`,这是一个复制/粘贴错误。我还使用“.GetThing(1234)”增强了示例,使它们更加真实。 (2认同)