I am using Swashbuckle.AspNetCore.Annotations
to enhance the generated documentation. I have a simple C# controller that has your standard Get, Post, Delete endpoints. My issues occurred when I added an additional HttpGet with a route parameter, which should be enough to differentiate and still generate the swagger documentation.
Everything seems to be ok until I try to modify the SwaggerResponse
as one endpoint /entities
returns a page of entities, where as the /entities/{id}
endpoint returns a single entity result.
I modified the attribute annotations:
[HttpGet]
[SwaggerOperation(
Summary = "summary here",
Description = "description",
OperationId = "GetPage",
Tags = new[] { "Entity" })]
[Produces("application/json")]
[SwaggerResponse(StatusCodes.Status200OK, type: typeof(PaginationResult<EntityTransferObject>))]
[SwaggerResponse(StatusCodes.Status401Unauthorized)]
[SwaggerResponse(StatusCodes.Status400BadRequest)]
public async Task<ActionResult> GetAsync(
[FromQuery] [SwaggerParameter("The entity type", Required = true)] string entityType,
[FromQuery] [SwaggerParameter("The page number to return", Required = true)]
int page,
[FromHeader(Name = "Authorization")] [SwaggerIgnore]
string token)
{
}
[HttpGet("{id:guid}")]
[SwaggerOperation(
Summary = "summary here",
Description = "description",
OperationId = "GetEntity",
Tags = new[] { "Entity" })]
[Produces("application/json")]
[SwaggerResponse(StatusCodes.Status200OK, type: typeof(ExecuteQueryResult<EntityTransferObject>))]
[SwaggerResponse(StatusCodes.Status401Unauthorized)]
[SwaggerResponse(StatusCodes.Status400BadRequest)]
public async Task<ActionResult> GetAsync(
[FromRoute] [SwaggerParameter("The entity id", Required = true)] Guid id,
[FromHeader(Name = "Authorization")] [SwaggerIgnore]
string token)
{
}
If I then generate the swagger documentation I am met with an error that it failed to load the API definition. If I change the swagger response type to be the same for the 2 /GET methods, it will work. It will also work if I only add the attribute to one endpoint.
If the endpoints are different, they should support different response types for a status code? I've tried using the .NET Core ProducesResponseType
and that results in the same issue. I have also tried adjusting the return type to be more specific e.g. Task<ActionResult<PaginationResult<EntityTransferObject>>>
and that has the same issue.
Is there another way to enhance the documentation output for the returned type for the 2 endpoints?
CodePudding user response:
It appears that swagger is getting upset because both endpoints return a type that contains the same transfer object.
e.g.
PaginationResult, which has a list of TransferObjects and the QueryResult that just has 1 TransferObject. Although different types, the TransferObject is resulting in a "can't use schemaId for type Y as it is already used for type Z".
I fixed this by adding the following line to the swagger config
services.AddSwaggerGen(
c =>
{
// Removed earlier config for simplicity
c.CustomSchemaIds(type => type.ToString());
});