Take the following code using ASP.NET Core 2.1:
[HttpGet("/unresolved")] public async Task<ActionResult<IEnumerable<UnresolvedIdentity>>> GetUnresolvedIdentities() { var results = await _identities.GetUnresolvedIdentities().ConfigureAwait(false); return results.ToList(); }
I would have thought since GetUnresolvedIdentities()
returns IEnumerable<UnresolvedIdentity>
that I could just return
return await _identities.GetUnresolvedIdentities().ConfigureAwait(false);
Except I can't, as I get this error:
CS0029 Cannot implicitly convert type
'System.Collections.Generic.IEnumerable<Data.Infrastructure.Models.UnresolvedIdentity>'
to'Microsoft.AspNetCore.Mvc.ActionResult<System.Collections.Generic.IEnumerable<Data.Infrastructure.Models.UnresolvedIdentity>>'
I need the .ToList()
, which is annoying as it's 2 lines rather than 1.
Why can't ActionResult<T>
figure out that GetUnresolvedIdentities()
returns an IEnumerable<>
and just return that?
The signature of GetUnresolvedIdentities
is:
Task<IEnumerable<UnresolvedIdentity>> GetUnresolvedIdentities();
A controller action returns something called an action result. An action result is what a controller action returns in response to a browser request. The ASP.NET MVC framework supports several types of action results including: ViewResult - Represents HTML and markup.
As you can see, the same action method “Index” is returning two different types named Content and View; if you want to return multiple types, you have to use base type as ActionResult.
The IActionResult return type is appropriate when multiple ActionResult return types are possible in an action. The ActionResult types represent various HTTP status codes. Any non-abstract class deriving from ActionResult qualifies as a valid return type.
Take this documentation from msdn: https://docs.microsoft.com/en-us/aspnet/core/web-api/action-return-types?view=aspnetcore-2.1#actionresultt-type
C# doesn't support implicit cast operators on interfaces. Consequently, conversion of the interface to a concrete type is necessary to use
ActionResult<T>
.
You can resolve this in a relatively tidy way by using Ok(...)
[HttpGet] public ActionResult<IEnumerable<MyDTOObject>> Get() => Ok(Repo.GetObjects()); [HttpGet] public async Task<ActionResult<IEnumerable<MyDTOObject>>> GetAsync() => Ok(await Repo.GetObjectsAsync());
Which assuming that GetObjects()
and GetObjectsAsync()
return a IEnumerable<MyDTOObject>
and Task<IEnumerable<MyDTOObject>>
respectively - allows you to skip .ToList()
or .ToListAsync()
.
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