Swashbuckle.AspNetCore
Swashbuckle.AspNetCore copied to clipboard
Support content type from ProducesResponseTypeAttribute
Using version 6.2.3
I have been trying to set the response type of one of my endpoints to "application/pdf". It works, sort of, when using the ProducesAttribute, like in the documentation, but adding another response type like 400 = application/json is not easy.
I would like to be able to use ProducesResponseTypeAttribute instead and it looks as if it follows the features as SwaggerResponseAttribute.
However, it seems the content-type from ProducesResponseTypeAttribute is not used in the schema:
// Works! content-type set to application/pdf
[SwaggerResponse(200, null, typeof(FileResult), "application/pdf")]
// Doesnt work content-type not set to application/pdf
[ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK, "application/pdf")]

It looks like it should be possible to get the content-type per status code.
I also just realized that when i define any content-type in the ProducesResponseType then the schema only contains the description and not the content:
Output of [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK, "application/pdf")]
"responses": {
"200": {
"description": "Success"
},
"400": {
"description": "Bad Request"
}
}
Output of [ProducesResponseType(typeof(FileResult), StatusCodes.Status200OK)]
"responses": {
"200": {
"description": "Success",
"content": {
"text/plain": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WeatherForecast"
}
}
},
"application/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WeatherForecast"
}
}
},
"text/json": {
"schema": {
"type": "array",
"items": {
"$ref": "#/components/schemas/WeatherForecast"
}
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"text/plain": {
"schema": {
"type": "string",
"format": "binary"
}
},
"application/json": {
"schema": {
"type": "string",
"format": "binary"
}
},
"text/json": {
"schema": {
"type": "string",
"format": "binary"
}
}
}
}
}
There is also a bug caused by this: When specifying a content type, the response type is ignored.
For these attributes:
[ProducesResponseType(200)]
[ProducesResponseType(typeof(ValidationProblemDetails), 400, "application/problem+json")]
The result is:

And for these attributes:
[ProducesResponseType(200)]
[ProducesResponseType(typeof(ValidationProblemDetails), 400)]
The result is:

I also bumped into this and use the SwaggerResponse workaround. This has been reported again in #2386.
I did notice that the implementation of ProducesResponseType only accepts the content-type parameter since .net 6.0, and the attribute does not make the supplied parameters publicly available. There is a property, but it is marked internal with a comment that it is meant for testing purposes(see here). But I don't know whether Swashbuckle needs to access these attributes directly.
I also encountered this issue. Swashbuckle leverages on ApiExplorer and not directly on the attribute.
From what I see, the generator requires the ModelMetadata to be populated https://github.com/domaindrivendev/Swashbuckle.AspNetCore/blob/master/src/Swashbuckle.AspNetCore.SwaggerGen/SwaggerGenerator/SwaggerGenerator.cs#L454 but it isn't the case when a content-type is provided in the ProducesResponseType attribute cause of the apiResponse.ApiResponseFormats being pre-populated https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.ApiExplorer/src/ApiResponseTypeProvider.cs#L207.
I'm not sure if it's an intended behavior on aspnetcore side but I think Swashbuckle can fallback on the ApiResponseType.Type property when ModelMetadata is null.
I'm noticing this too. In version 6.5.0. With the following attributes:
[HttpGet("{id}", Name = "GetAppointmentRequest")]
[SwaggerResponse(StatusCodes.Status404NotFound, null, typeof(ProblemDetails), "application/problem+json")]
[ProducesResponseType(typeof(AppointmentRequestDto), StatusCodes.Status200OK, MediaTypeNames.Application.Json)]
ASP.NET Core produces the right content-type, but the generated OpenAPI doesn't reflect what ASP.NET is doing.
If I include ProducesResponseType for the 404:
[HttpGet("{id}", Name = "GetAppointmentRequest")]
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound, "application/problem+json")]
[SwaggerResponse(StatusCodes.Status404NotFound, null, typeof(ProblemDetails), "application/problem+json")]
[ProducesResponseType(typeof(AppointmentRequestDto), StatusCodes.Status200OK, MediaTypeNames.Application.Json)]
the OpenAPI has even less detail:
I am facing the same bug. I cannot make proper swagger for FileStreamResult endpoint in version 6.5