Can’t decide between Task, IActionResult and ActionResult

Here is a quick comparison of the different return options:

Specific type

public Thing Get() {
    return Context.Things.GetThing(1234);
}

This is OK if the action will always return one possible type. However, most actions may return exceptions (i.e. status codes other than 200) that have different types.

IActionResult type

This solves the problem above as the IActionResult return type covers different return types.

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

For asynchronous action, use Task<IActionResult>:

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

ActionResult type

ASP.NET Core 2.1 introduced the ActionResult<T> return type which offers the following benefits over the IActionResult type:

1- The action’s expected return type is inferred from the T in ActionResult<T>. If you decorate your action with the [ProducesResponseType] attribute, you no longer need to explicitly specify its Type property. For example, you can simply use [ProducesResponseType(200)] instead of [ProducesResponseType(200, Type = typeof(Thing))].

2- T converts to ObjectResult, which means return new ObjectResult(T); is simplified to return T;.

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

For asynchronous action, use Task<ActionResult<T>>:

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

For more details, you can refer to the MSDN page Controller action return types in ASP.NET Core Web API.

Leave a Comment