我有一个只有一个动作的控制器。在这个操作方法中,我调用了一个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>更好,即使结果看起来是一样的。
发布于 2018-01-24 13:25:37
Task< T>
专业版
单元测试不需要任何类型转换,
Product product = await controller.Get();最大的好处是,您的单元测试变得真正独立于底层HTTP Stack。
Swagger不需要任何额外的属性来生成响应模式,因为swagger可以很容易地检测到结果类型。
另一个很大的好处是,当逻辑保持不变时,您可以在其他控制器中重用您的控制器。
此外,在返回之前避免await会略微提高性能,因为这部分代码不需要任务状态机。我认为未来的C#版本将省略单个等待作为编译器优化。
Con
返回错误状态码需要抛出异常..
throw new HttpStatusException(404, "File not found");
throw new HttpStatusException(409, "Unauthorized");Task< IAsyncResult>
专业版
您可以返回HTTP状态代码,例如
return NotFound(); // (Status Code = 404)
return Unauthorized(); // (Status Code = 409)Con
单元测试需要额外的强制转换。
Product productResult = ((await controller.Get()) as OkResult).Result as Product;由于这种转换,很难在其他控制器中重用您的控制器,从而导致逻辑重复。
Swagger生成器需要额外的属性才能生成响应架构
[ProducesResponseType(typeof(Product), 200)]只有当你处理的逻辑不是单元测试的一部分,并且不是你的业务逻辑的一部分,比如OAuth与第三方服务的集成,你想更多地关注基于IActionResult的结果,比如Challenge,Redirect等时,才建议使用这种方法。
发布于 2018-01-24 13:06:29
操作可以返回任何东西,大多数情况下,它们返回一个产生响应的IActionResult (异步方法为Task<IActionResult> )的实例。action方法负责选择它返回的响应类型,action result执行响应。
如果一个操作返回一个IActionResult实现者,并且控制器继承自控制器,则开发人员有许多与许多选择相对应的助手方法。返回非IActionResult类型对象的操作的结果将使用适当的IOutputFormatter实现进行序列化。
对于具有多种返回类型或选项的非平凡操作(例如,根据执行的操作结果有不同的HTTP状态码),返回类型优先选择IActionResult。
发布于 2018-01-24 16:03:12
ASP.NET MVC是一个conventions over configuration框架。这意味着你的代码的任何未来的维护者,包括你未来的自己,将期望代码以某种方式编写,以便减少你在进行更改或添加时必须检查的类文件的数量。
虽然两个技术上不同的选项的结果可能是相同的,但传统方法是异步/等待结果。任何不同于此的约定都可能会给未来的维护者带来混乱。此外,MVC的未来版本可能会以未知的方式破坏您的代码,因为您没有遵循约定。
软件开发团队的良好领导包括灌输通过简化潜在的未来代码维护来减少组织的总体人力需求的愿望。你的经理可能正在尝试推广这一概念。
https://stackoverflow.com/questions/48415095
复制相似问题