asp.net-coreswaggerswagger-2.0

How to annotate controller method that returns different content types of responses


I've a controller to download a file which can return either application/zip content type or application/json in case of any error. I'm trying to annotate controller to produce the correct swagger.json

[HttpGet("download/{id}")]
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status200OK)]
[ProducesResponseType(typeof(FileStreamResult), StatusCodes.Status206PartialContent)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status404NotFound)]
[ProducesResponseType(typeof(ErrorResponse), StatusCodes.Status416RangeNotSatisfiable)]
[Produces(MediaTypeNames.Application.Zip)]
public ActionResult Download(Guid id)
{
}

But in this case the swagger.json will contain responses like below:

"responses": {
      "200": {
        "description": "Returns the content of the file",
        "content": {
          "application/zip": {
            "schema": {
              "type": "string",
              "format": "binary"
            }
          }
        }
      },
      "206": {
        "description": "Supports range requests",
        "content": {
          "application/zip": {
            "schema": {
              "type": "string",
              "format": "binary"
            }
          }
        }
      },
      "404": {
        "description": "The file was not found",
        "content": {
          "application/zip": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "416": {
        "description": "The range is not satisfiable",
        "content": {
          "application/zip": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }
    }
  }

But I would like define content type application/json for 404 and 416. Is there any way how to achieve this?

Desired state:

      "404": {
        "description": "The file was not found",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      },
      "416": {
        "description": "The range is not satisfiable",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorResponse"
            }
          }
        }
      }

Solution

  • Try this:

    // For brevity:
    using static Microsoft.AspNetCore.Http.StatusCodes;
    using Mime = MediaTypeNames.Application;
    
    [HttpGet("download/{id}")]
    [ProducesResponseType( typeof(FileStreamResult), Status200OK                 , Mime.Zip  )]
    [ProducesResponseType( typeof(FileStreamResult), Status206PartialContent     , Mime.Zip  )]
    [ProducesResponseType( typeof(ErrorResponse)   , Status404NotFound           , Mime.Json )]
    [ProducesResponseType( typeof(ErrorResponse)   , Status416RangeNotSatisfiable, Mime.Json )]
    public async Task<ActionResult> Download( Guid id, CancellationToken cancellationToken )
    {
        throw new NotImplementedException();
    }