Support description for response status code in the Open API
Is there an existing issue for this?
- [X] I have searched the existing issues
Is your feature request related to a problem? Please describe the problem.
Hi,
In .Net 7, there is no way to add a custom response status code description with Produces<>() method. And status code descriptions are fixed for status codes (for example for 400 and 401 it is client error):
endpoints.MapPost("/", CreateProducts)
.WithOpenApi(operation => new(operation)
{
Summary = "Creating a New Product", Description = "Creating a New Product"
})
.RequireAuthorization()
.Produces<CreateProductResponse>(StatusCodes.Status201Created)
.Produces<StatusCodeProblemDetails>(StatusCodes.Status401Unauthorized)
.Produces<StatusCodeProblemDetails>(StatusCodes.Status400BadRequest)
.WithName("CreateProduct")
.WithDisplayName("Create a new product."));

Describe the solution you'd like
Please add a description to Produces<>() overload for changing default status code response description. This feature exists in Swashbuckle.AspNetCore.Annotations package with bellow functionality
endpoints.MapPost("/", CreateProducts)
.WithOpenApi(operation => new(operation)
{
Summary = "Creating a New Product", Description = "Creating a New Product"
})
.RequireAuthorization()
.Produces<CreateProductResponse>(StatusCodes.Status201Created)
.WithName("CreateProduct")
.WithDisplayName("Create a new product.")
.WithMetadata(new SwaggerResponseAttribute(
StatusCodes.Status401Unauthorized,
"UnAuthorized request.",
typeof(StatusCodeProblemDetails)))
.WithMetadata(new SwaggerResponseAttribute(
StatusCodes.Status400BadRequest,
"Invalid input for creating product.",
typeof(StatusCodeProblemDetails)))
.WithMetadata(
new SwaggerResponseAttribute(
StatusCodes.Status201Created,
"Product created successfully.",
typeof(CreateProductResponse)));

Additional context
No response
cc @captainsafia
@mehdihadeli You should be able to do this by leveraging the WithOpenApi extension method:
endpoints.MapPost("/", CreateProducts)
.WithOpenApi(operation =>
{
operation.Responses["200"].Description = "Your description here";
return operation;
});
Hi @mehdihadeli. We have added the "Needs: Author Feedback" label to this issue, which indicates that we have an open question for you before we can take further action. This issue will be closed automatically in 7 days if we do not hear back from you by then - please feel free to re-open it if you come back to this issue after that time.
@captainsafia Thanks, let me check, but it is better we have a separate method like WithSummary and WithDescription for this also
@captainsafia Thanks, let me check, but it is better we have a separate method like
WithSummaryandWithDescriptionfor this also
You should be able to create these kinds of wrappers yourself doing something like:
public IEndpointConventionBuilder WithResponseDescription(this IEndpointConventionBuilder builder, int statusCode, string description)
{
builder.WithOpenApi(operation =>
{
operation.Responses[$"{statusCode}"].Description = description;
return operation;
});
return builder;
}
The reason we introduced the WithOpenApi extension method was to provide a catch-all approach for handling different parts of the OpenAPI annotation. So instead of providing an extension method for each and every aspect (which can get really bloated), we provide the more robust API and then users can implement their own extension methods for particular areas they are interested in.
Make sense, Thanks :)
@captainsafia Hi,
Is it possible we add status response schema type also in this extension (WithOpenApi) method instead of calling a separate method .Produces<StatusCodeProblemDetails>(StatusCodes.Status401Unauthorized)?
I want something like this:
.WithResponseDescription<StatusCodeProblemDetails>(StatusCodes.Status401Unauthorized, "Unauthorized")
Should I call .Produces<StatusCodeProblemDetails>(StatusCodes.Status401Unauthorized) after WithOpenApi inner extension method or there is a way to do this inner WithOpenApi?
@captainsafia Hi, Is it possible we add status response schema type also in this extension (WithOpenApi) method instead of calling a separate method
.Produces<StatusCodeProblemDetails>(StatusCodes.Status401Unauthorized)?I want something like this:
.WithResponseDescription<StatusCodeProblemDetails>(StatusCodes.Status401Unauthorized, "Unauthorized")Should I call
.Produces<StatusCodeProblemDetails>(StatusCodes.Status401Unauthorized)afterWithOpenApiinner extension method or there is a way to do this innerWithOpenApi?
Yep, you'll have to do this.
At the moment, response schema generation is done in the Swashbuckle.AspNetCore library, not in the the Microsoft.OpenApi package. Swashbuckle.AspNetCore expects to get the response type in a Produces metadata item on the endpoint. It takes the type defined there, generates the schema, and then applies it to the schema property in the request.
What this means, is that if you wanted to wrap this functionality in one step, you'd have to do call both WithOpenApi in your extension method to set the custom description method and builder.Produces to add the response type to metadata so Swashbuckle can pick it up to generate the schema.
public IEndpointConventionBuilder WithResponseDescription<TResponse>(this IEndpointConventionBuilder builder, int statusCode, string description)
{
builder.Produces<TResponse>(statusCode);
builder.WithOpenApi(operation =>
{
operation.Responses[$"{statusCode}"].Description = description;
return operation;
});
return builder;
}
@captainsafia Hi, Is it possible we add status response schema type also in this extension (WithOpenApi) method instead of calling a separate method
.Produces<StatusCodeProblemDetails>(StatusCodes.Status401Unauthorized)? I want something like this:.WithResponseDescription<StatusCodeProblemDetails>(StatusCodes.Status401Unauthorized, "Unauthorized")Should I call
.Produces<StatusCodeProblemDetails>(StatusCodes.Status401Unauthorized)afterWithOpenApiinner extension method or there is a way to do this innerWithOpenApi?Yep, you'll have to do this.
At the moment, response schema generation is done in the
Swashbuckle.AspNetCorelibrary, not in the theMicrosoft.OpenApipackage.Swashbuckle.AspNetCoreexpects to get the response type in aProducesmetadata item on the endpoint. It takes the type defined there, generates the schema, and then applies it to theschemaproperty in the request.What this means, is that if you wanted to wrap this functionality in one step, you'd have to do call both
WithOpenApiin your extension method to set the custom description method andbuilder.Producesto add the response type to metadata so Swashbuckle can pick it up to generate the schema.public IEndpointConventionBuilder WithResponseDescription<TResponse>(this IEndpointConventionBuilder builder, int statusCode, string description) { builder.Produces<TResponse>(statusCode); builder.WithOpenApi(operation => { operation.Responses[$"{statusCode}"].Description = description; return operation; }); return builder; }
Thanks for your response,
You mean about Swashbuckle.AspNetCore is using this Swashbuckle.AspNetCore.Annotations package and this attribute SwaggerResponseAttribute?
Something like this:
builder.WithMetadata(new SwaggerResponseAttribute(
StatusCodes.Status401Unauthorized,
"UnAuthorized request.",
typeof(StatusCodeProblemDetails)))
You mean about Swashbuckle.AspNetCore is using this Swashbuckle.AspNetCore.Annotations package and this attribute SwaggerResponseAttribute?
Nope, Swashbuckle is using the ProducesResponseTypeAttribute which is what the Produces extension methods referenced in the code above add to endpoint's metadata.
Ok, Thanks.