I upgraded to Swashbuckle v5, and was trying to update a project that uses the Microsoft.AspNetCore.Mvc.Versioning. It uses an operation filter like such:
public void Apply(Operation operation, OperationFilterContext context)
{
var apiDescription = context.ApiDescription;
operation.Deprecated = apiDescription.IsDeprecated();
if (operation.Parameters == null)
{
return;
}
// REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/412
// REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/413
foreach (var parameter in operation.Parameters.OfType<NonBodyParameter>())
{
var description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name);
if (parameter.Description == null)
{
parameter.Description = description.ModelMetadata?.Description;
}
if (parameter.Default == null)
{
parameter.Default = description.DefaultValue;
}
parameter.Required |= description.IsRequired;
}
}
With SwaggerDocument no longer used in v5, I couldn't find a NonBodyParameter equivalent in OpenAPI model.
Can anyone tell me the appropriate class to use for that in OpenAPI?
In OpenAPI v3, body parameters are split out into a separate property called RequestBody. So, I think you may be able to remove OfType filter entirely as all values in the collection are "non-body"
Yup, it did work w/o the OfType. However, the OpenAPI doesn't allow you to set a default value. I think the MS API Version maintainer will have to setup the API versions as a OpenAPI options list value, and then pick the default. I punted on this for now, and just went with version-in-url pattern.
Yup, it did work w/o the OfType. However, the OpenAPI doesn't allow you to set a default value. I think the MS API Version maintainer will have to setup the API versions as a OpenAPI options list value, and then pick the default. I punted on this for now, and just went with version-in-url pattern.
How did you change your code with RequestBody?
For my side i applied the following changes, since the OpenApiParameter has been made as public class since then
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
if (operation.Parameters == null)
{
return;
}
// REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/412
// REF: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/413
foreach (var parameter in operation.Parameters)
{
var description = context.ApiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name);
var routeInfo = description.RouteInfo;
if (string.IsNullOrEmpty(parameter.Name))
{
parameter.Name = description.ModelMetadata?.Name;
}
if (parameter.Description == null)
{
parameter.Description = description.ModelMetadata?.Description;
}
if (routeInfo == null)
{
continue;
}
parameter.Required |= !routeInfo.IsOptional;
}
// Overwrite description for shared response code
operation.Responses["400"].Description = "Invalid query parameter(s). Read the response description";
operation.Responses["401"].Description = "Authorization has been denied for this request";
}
// Overwrite description for shared response code operation.Responses["400"].Description = "Invalid query parameter(s). Read the response description"; operation.Responses["401"].Description = "Authorization has been denied for this request";
I found that for a successful response, the "operation.Responses" dictionary only contains an item for "200".
So I think a slightly more defensive code is needed, like this:
// Overwrite description for common response codes
var statusBadRequest = StatusCodes.Status400BadRequest.ToString(CultureInfo.InvariantCulture);
if (operation.Responses.ContainsKey(statusBadRequest))
{
operation.Responses[statusBadRequest].Description = "Invalid query parameter(s). Read the response description";
}
var statusUnauthorized = StatusCodes.Status401Unauthorized.ToString(CultureInfo.InvariantCulture);
if (operation.Responses.ContainsKey(statusUnauthorized))
{
operation.Responses[statusUnauthorized].Description = "Authorization has been denied for this request";
}
This may be relevant
https://github.com/Microsoft/aspnet-api-versioning/issues/429
So not cool that you decided to break everything
Most helpful comment
How did you change your code with RequestBody?