Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

IActionResult vs ActionResult<T> vs T - Why doesn't ActionResult<T> work?

I'm working on a .NET 5 web api and I have the following code that throws an error when I try to return NotFound().

[ApiController]
public class Download : ControllerBase
{
    // Constructor and members omitted...

    [HttpGet( Routes.KatApps.Download )]
    [SwaggerOperation(
        Summary = "Find and download KatApp kaml file based on precedence of folders passed in",
        Description = "Find and download KatApp kaml file based on precedence of folders passed in",
        OperationId = "KatApps." + nameof( Routes.KatApps.Download ),
        Tags = new[] { "KatApps" } )]
    [ProducesResponseType( StatusCodes.Status200OK )]
    [ProducesResponseType( StatusCodes.Status304NotModified )]
    [ProducesResponseType( typeof( ValidationProblemDetails ), StatusCodes.Status401Unauthorized )]
    [ProducesResponseType( typeof( ValidationProblemDetails ), StatusCodes.Status404NotFound )]
    public async Task<ActionResult<FileStreamResult>> HandleAsync( [FromQuery] Parameters parameters )
    {
        using ( var cn = await dbConnectionFactory.CreateDataLockerConnectionAsync() )
        {
            foreach ( var folder in parameters.Folder )
            {
                var keyInfo = await cn.QueryBuilder( $@"Query Omitted" ).QueryFirstOrDefaultAsync<CacheDownloadInfo>();

                if ( keyInfo != null )
                {
                    return await CachedOrModifiedAsync( keyInfo, dbConnectionFactory );
                }
            }

            return NotFound();
        }
    }
}

protected async Task<FileStreamResult> CachedOrModifiedAsync( CacheDownloadInfo cacheDownloadInfo, IDbConnectionFactory dbConnectionFactory )
{
    // Code to return FileStreamResult
}

But when I hit the NotFound call, I get:

System.ArgumentException: Invalid type parameter 'Microsoft.AspNetCore.Mvc.FileStreamResult' specified for 'ActionResult<T>'.

enter image description here

The weird thing is, I have another controller action (skipping all the setup code to just show signature and start) that works fine when I return NotFound().

public async Task<ActionResult<ManagedFileInfo>> HandleAsync( [FromQuery] Parameters parameters )
{
    using ( var cn = await dbConnectionFactory.CreateDataLockerConnectionAsync() )
    {
        var liveFiles = ( await QueryFileVersions( cn, new[] { parameters.Name }, parameters.Folder ) ).ToArray();

        if ( liveFiles.Length == 0 )
        {
            return NotFound();
        }

Anyone have any idea why my first method does not work?

like image 380
Terry Avatar asked Oct 15 '25 08:10

Terry


1 Answers

Doh...in case anyone else runs into this. The problem is FileResultStream is an ActionResult, so it was not correct to use ActionResult<T> where T is another ActionResult in this scenario. I am using IActionResult and then updating my attribute to:

[ProducesResponseType( typeof( FileStreamResult ), StatusCodes.Status200OK )]

If there is better way, let me know.

like image 183
Terry Avatar answered Oct 16 '25 21:10

Terry