IActionResult против ActionResult против T — Почему ActionResult не работает?

#c# #asp.net-core #asp.net-core-webapi

#c# #asp.net-ядро #asp.net-core-webapi

Вопрос:

Я работаю над веб-api .NET 5, и у меня есть следующий код, который выдает ошибку при попытке возврата 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
}
 

Но когда я нажимаю на NotFound вызов, я получаю:

Система.Исключение ArgumentException: недопустимый параметр типа ‘Microsoft.AspNetCore.Mvc.FileStreamResult’ указан для ‘ActionResult<T>’ .

введите описание изображения здесь

Странно то, что у меня есть другое действие контроллера (пропуская весь установочный код, чтобы просто показать подпись и запустить), которое отлично работает, когда я возвращаюсь 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();
        }
 

У кого-нибудь есть идеи, почему мой первый метод не работает?

Комментарии:

1. Возможно , вы также захотите исключить запрос из своего скриншота…

2. Я думаю, это потому, что вы используете тип результата действия как T. Во-вторых, вы используете модель, которую возвращаете в виде данных.

3. @IanKemp был опущен только в реальном коде, чтобы убрать некоторый шум. В запросе нет ничего секретного. Спасибо.

Ответ №1:

Doh…in на случай, если кто-нибудь еще столкнется с этим. Проблема в том, что FileResultStream это an ActionResult , поэтому было неправильно использовать ActionResult<T> , где T — другое ActionResult в этом сценарии. Я использую IActionResult , а затем обновляю свой атрибут до:

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

Если есть лучший способ, дайте мне знать.