How can I change order the operations are listed in a group in Swashbuckle?
Solution 1
Have you seen this issue? https://github.com/domaindrivendev/Swashbuckle/issues/11
public class CustomDocumentFilter : IDocumentFilter
{
public void Apply(SwaggerDocument swaggerDoc, SchemaRegistry schemaRegistry, System.Web.Http.Description.IApiExplorer apiExplorer)
{
//make operations alphabetic
var paths = swaggerDoc.Paths.OrderBy(e => e.Key).ToList();
swaggerDoc.Paths = paths.ToDictionary(e => e.Key, e => e.Value);
}
}
and then:
c.DocumentFilter<CustomDocumentFilter>();
Solution 2
Had the same issue, and finally managed to fix it with the official doc. provided on this URL https://github.com/domaindrivendev/Swashbuckle.AspNetCore#change-operation-sort-order-eg-for-ui-sorting
services.AddSwaggerGen(c =>
{
...
c.OrderActionsBy((apiDesc) => $"{apiDesc.ActionDescriptor.RouteValues["controller"]}_{apiDesc.HttpMethod}");
};
Is an easier and clearer path to solve it :)
Solution 3
In order to order the Operations of controller in swagger OpenApi paths json spec you could create a custom Attribute OrderAttribute and then a IDocumentFilter which will reorder the OpenApiPaths.
public class OperationsOrderingFilter : IDocumentFilter
{
public void Apply(OpenApiDocument openApiDoc, DocumentFilterContext context)
{
Dictionary<KeyValuePair<string, OpenApiPathItem>,int> paths = new Dictionary<KeyValuePair<string, OpenApiPathItem>, int>();
foreach(var path in openApiDoc.Paths)
{
OperationOrderAttribute orderAttribute = context.ApiDescriptions.FirstOrDefault(x=>x.RelativePath.Replace("/", string.Empty)
.Equals( path.Key.Replace("/", string.Empty), StringComparison.InvariantCultureIgnoreCase))?
.ActionDescriptor?.EndpointMetadata?.FirstOrDefault(x=>x is OperationOrderAttribute) as OperationOrderAttribute;
if (orderAttribute == null)
throw new ArgumentNullException("there is no order for operation " + path.Key);
int order = orderAttribute.Order;
paths.Add(path, order);
}
var orderedPaths = paths.OrderBy(x => x.Value).ToList();
openApiDoc.Paths.Clear();
orderedPaths.ForEach(x => openApiDoc.Paths.Add(x.Key.Key, x.Key.Value));
}
}
then the attribute would be
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class OperationOrderAttribute : Attribute
{
public int Order { get; }
public OperationOrderAttribute(int order)
{
this.Order = order;
}
}
the registration of the filter in swagger would be
services.AddSwaggerGen(options =>
{
options.DocumentFilter<OperationsOrderingFilter>();
}
and an example of a controller method with the attribute would be:
[HttpGet]
[OperationOrder(2)]
[Route("api/get")]
public async Task<ActionResult> Get(string model)
{
...
}
Comments
-
lpacheco almost 2 years
I'm using Swashbuckle to generate Swagger UI. It has options for choosing a grouping key (controller by default) and the ordering of the groups, but I would like to choose an order for the operations in a group so that
GET
appears always beforeDELETE
for example.I've found how to implement document filters and I can get and order
ApiDescriptions
byHttpMethod
, but changing the order inApiDescriptions
doesn't reflect in the generated Swagger UI and I can't find how to persist the order inswaggerDoc
.SwaggerDocument
has apaths
property, but thePathItem
in it has each HTTP method as a property, so I can't figure how to choose an order of presentation for them. Eventough, when the Swagger UI for my API is generated, different controllers get different method order in the page.Should I manually reorder the methods implementation in my controller instead?