Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActionResult<IEnumerable<T>> has to return a List<T>

Tags:

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(); 
like image 931
Stuart Avatar asked Aug 08 '18 08:08

Stuart


People also ask

What does ActionResult return?

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.

Which return type should be used when multiple ActionResult return types are possible in an action?

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.

What is the difference between IActionResult and 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.


2 Answers

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>.

like image 53
V0ldek Avatar answered Sep 27 '22 20:09

V0ldek


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().

like image 28
PhonicUK Avatar answered Sep 27 '22 20:09

PhonicUK