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"
}
}
}
}
[Produces(MediaTypeNames.Application.Zip)]
attribute because that sets a Content-Type
for all other defined responses.[ProducesErrorResponseType]
attribute, but it lacks a constructor overload for specifying exact HTTP status-codes and Content-Type
values.[ProducesResponseType]
for everything, including client-errors, but use a different ctor overload:
ProducesResponseTypeAttribute(Type, Int32, String, params String[])
ctor lets you specify the C# DTO Type
, the HTTP status code, and Content-Type
(the trailing params String[]
parameter is for "additional content-types" which I honestly have no idea about, but we can safely ignore it).Content-Type
set using \[ProducesContentType\]
. I believe it's fixed now, but let me know if it doesn't work and I'll update my answer.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();
}