I have a controller with one action. In this action method, I have an async
method that I call and that is it. This is the code that I am using:
[HttpGet]
public Task<MyObject> Get()
{
return _task.GetMyObject()
}
This serializes correctly into the JSON I expect from it. Now my manager insists that the signature should be changed to the following:
[HttpGet]
public async Task<IActionResult> Get()
{
var data = await_task.GetMyObject();
return Ok(data);
}
I'm of the belief that there is no reason for the code to await
in the controller and can just return the Task
because nothing afterwards depends on the result. Apart from the extra code generation (creation of state machine etc.) done for the await
, are there any implications from a WebApi
point of view of these approaches? To clarify, I want to know if returning an IActionResult
is better than to just return Task<MyObject>
even tho it seems like the results are the same.
Task< T>
Pro
Unit tests do not require any casting,
Product product = await controller.Get();
Big advantage is, your unit tests become truly independent of underlying HTTP Stack.
Swagger does not need any extra attribute to generate response schema as swagger can easily detect result type.
Another big advantage is, you can reuse your controller in some other controller when the logic remains same.
Also avoiding await
before return gives slight improvement in performance as that part of code does not need Task state machine. I think future C# version will omit single await as compiler optimization.
Con
Returning error status code requires throwing exception..
throw new HttpStatusException(404, "File not found");
throw new HttpStatusException(409, "Unauthorized");
Task< IAsyncResult>
Pro
You can return HTTP Status code such as
return NotFound(); // (Status Code = 404)
return Unauthorized(); // (Status Code = 409)
Con
Unit testing requires extra casting..
Product productResult = ((await controller.Get()) as OkResult).Result as Product;
Due to such casting, it becomes difficult to reuse your controllers in some other controller, leading to duplication of logic.
Swagger generator requires extra attribute to generate response schema
[ProducesResponseType(typeof(Product), 200)]
This approach is only recommended when you are dealing with logic that is not part of unit tests, and not part of your business logic such as OAuth
integration with third party services where you want to focus more on IActionResult
based results such as Challenge
, Redirect
etc.
Actions can return anything, mostly they return an instance of IActionResult
(or Task<IActionResult>
for async methods) that produces a response. The action method is responsible for choosing what kind of response it return and the action result does the responding.
If an action returns an IActionResult
implementor and the controller inherits from Controller, developers have many helper methods corresponding to many of the choices. Results from actions that return objects that are not IActionResult
types will be serialized using the appropriate IOutputFormatter
implementation.
For non-trivial actions with multiple return types or options (for example, different HTTP status codes based on the result of operations performed), prefer IActionResult
as the return type.
ASP.NET MVC is a conventions over configuration framework. This means any future maintainer of your code, including your future self, will expect code to be written a certain way in order to reduce the number of class files you have to inspect to make changes or additions.
While the result may be the same from your two technically different options, the conventional approach is to async/await your results. Anything other than that convention will potentially cause confusion for future maintainers. Additionally, future releases of MVC may break your code in unknown ways as you did not follow the convention.
Good leadership of software development teams includes instilling a desire to reduce overall manpower needs for the organization by simplifying potential future maintenance of the code. Your manager may be trying to promote this concept.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With