繁体   English   中英

异步任务 <IActionResult> vs任务 <T>

[英]async Task<IActionResult> vs Task<T>

我有一个控制器一个动作。 在这个动作方法中,我有一个我调用的async方法,就是这样。 这是我正在使用的代码:

[HttpGet]
public Task<MyObject> Get()
{
    return _task.GetMyObject()
}

这正确地序列化为我期望的JSON。 现在我的经理坚持要将签名更改为以下内容:

[HttpGet]
public async Task<IActionResult> Get()
{
    var data = await_task.GetMyObject();
    return Ok(data);
}

我相信没有理由在控制器中await代码并且可以返回Task因为之后没有任何东西取决于结果。 除了为await做的额外代码生成(创建状态机等)之外, WebApi对这些方法的观点是否有任何影响? 为了澄清,我想知道返回IActionResult是否比返回Task<MyObject>更好,即使结果看起来是相同的。

任务<T>

单元测试不需要任何铸造,

 Product product = await controller.Get();

最大的优点是,您的单元测试真正独立于底层HTTP堆栈。

Swagger不需要任何额外的属性来生成响应模式,因为swagger可以轻松地检测结果类型。

另一个很大的优点是,当逻辑保持不变时,您可以在其他控制器中重用控制器。

在返回之前避免await性能略有提高,因为该部分代码不需要任务状态机。 我认为未来的C#版本将省略单个等待编译器优化。

精读

返回错误状态代码需要抛出异常..

    throw new HttpStatusException(404, "File not found");
    throw new HttpStatusException(409, "Unauthorized");

任务<IAsyncResult>

您可以返回HTTP状态代码,例如

 return NotFound(); // (Status Code = 404)
 return Unauthorized(); // (Status Code = 409)

精读

单元测试需要额外的铸件..

 Product productResult = ((await controller.Get()) as OkResult).Result as Product;

由于这种转换,很难在其他控制器中重用控制器,导致逻辑重复。

Swagger生成器需要额外的属性来生成响应模式

 [ProducesResponseType(typeof(Product), 200)]

只有在处理不属于单元测试的逻辑时,才建议使用此方法,而不是业务逻辑的一部分,例如OAuth与第三方服务的集成,您希望更多地关注基于IActionResult的结果,例如ChallengeRedirect等。

动作可以返回任何内容,主要是返回产生响应的IActionResult (或异步方法的Task<IActionResult> )实例。 action方法负责选择返回的响应类型以及响应的操作结果。

如果一个动作返回一个IActionResult实现者并且控制器继承自Controller,那么开发人员有许多与许多选择相对应的辅助方法。 返回非IActionResult类型对象的操作的结果将使用适当的IOutputFormatter实现进行序列化。

对于具有多个返回类型或选项的非平凡操作(例如,基于所执行操作的结果的不同HTTP状态代码),更喜欢IActionResult作为返回类型。

ASP.NET MVC是一种基于配置框架的约定 这意味着您的代码的任何未来维护者,包括您未来的自我,都希望代码能够以某种方式编写,以减少您必须检查以进行更改或添加的类文件的数量。

虽然结果可能与您的两个技术上不同的选项相同,但传统方法是异步/等待您的结果。 除了该约定之外的任何其他内容都可能会对未来的维护者造成混淆。 此外,未来版本的MVC可能会以未知的方式破坏您的代码,因为您没有遵循惯例。

软件开发团队的良好领导包括通过简化代码的潜在未来维护来灌输降低组织总体人力需求的愿望。 您的经理可能正试图推广这一概念。

ASP.NET核心团队在统一MVC和WEB API(Controller和ApiController)的同时,抽象了IActionResult以实现强大的异常处理机制。

抛出控制流的异常是对行动方法的反模式。

[HttpGet]
public async Task<MyObject> Get()
{
    var data = await _task.GetMyObject()
    if(data == null)
    {
        return NotFound(); //Or, return Request.CreateResponse(HttpStatusCode.NotFound)
        // Versus, throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.NotFound));
    }

    return Ok(data);
}

注意: NotFound()Ok()等是WEBAPI2时代的IHttpActionResult事物并不是asp.net核心的新手。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM