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

17,475

Solution 1

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

Solution 2

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

Share:
17,475

Related videos on Youtube

Stuart
Author by

Stuart

Senior Software Developer doing C#, IoT, Azure. Also experienced in WPF, MVVM, Winforms, EF and SQL.

Updated on September 15, 2022

Comments

  • Stuart
    Stuart over 1 year

    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();
    
    • Vladi Pavelka
      Vladi Pavelka over 5 years
      @Corak because you can't task.ToList(). (await task).ToList() would work though
    • Tseng
      Tseng over 5 years
      You can wrap it around in ActionTask with the Ok helper method: return Ok(await _identities.GetUnresolvedIdentities());. P.S. you shouldn't call .ConfigureAwait(false) inside the controllers, unless you're 100% certain about the consequences (even though its not that much of an issue these days as it was in legacy ASP.NET). Its advised to always use it in general purpose libraries where its unknown in which context the library will be used
    • poke
      poke over 5 years
      You actually don’t need to use ConfigureAwait anywhere with ASP.NET Core since it does not have a synchronization context.
    • Andrei Tătar
      Andrei Tătar
      Because IEnumerable is different than IEnumerable<T>. Either change _identities.GetUnresolvedIdentities return type or your controller return type.