Timothy
Timothy

Reputation: 41

Sorting the Schemas portion of a Swagger page using Swashbuckle

On my Swagger page, I am (mostly) able to order the operations as described on the Swashbuckle page.

Below the operations is a "Schemas" section showing the data structures used by the actions. These data structures appear in a arbitrary order. I would like to sort them.

The question Swagger sort Schema Defintions superficially looks like the same question, but in that question "sort" is used in the sense of "sorting the items into different bins", not "ordering a list" which is what I want.

I have made a document filter that "works", but when I look at the code I wrote, I die a little inside.

Is there a more correct way to do this?

Edit: To be specific, what I object to about this code is that it is "working" by sorting the entries in a Dictionary, which is just bad ( see this question ).

Turns out the answer was simply to use a SortedDictionary:

        openApiDoc.Components.Schemas = new System.Collections.Generic.SortedDictionary<string, OpenApiSchema>(openApiDoc.Components.Schemas);

Upvotes: 2

Views: 3869

Answers (2)

Kingsley
Kingsley

Reputation: 161

This wouldn't change the final display order for me, but MikeBeaton's suggestion whilst reporting a Sort Schema Issue on GitHub worked like a charm..

app.UseSwagger(c =>
{
    c.PreSerializeFilters.Add((swagger, _) =>
    {
        if (swagger.Components != null && swagger.Components.Schemas != null)
        {
            var replacement = new Dictionary<string, OpenApiSchema>();
            foreach (var kv in swagger.Components.Schemas.OrderBy(p => p.Key))
            {
                replacement.Add(kv.Key, kv.Value);
            }
            swagger.Components.Schemas = replacement;
        }
    });
})

Upvotes: 0

Bellarmine Head
Bellarmine Head

Reputation: 3647

Actually, you were on the right track with the document filter!

In Startup.cs, ConfigureServices method:-

services.AddSwaggerGen(c =>
{
    // ...

    // For our document filtering needs.
    c.DocumentFilter<DocumentFilter>();
});

And here is the document filter implementation:-

using System.Linq;

public class DocumentFilter : IDocumentFilter
{
    public DocumentFilter()
    {
    }

    // Implements IDocumentFilter.Apply().
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        if (swaggerDoc == null)
            return;

        // Re-order the schemas alphabetically.
        swaggerDoc.Components.Schemas = swaggerDoc.Components.Schemas.OrderBy(kvp => kvp.Key, StringComparer.InvariantCulture)
            .ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
    }
}

when I look at the code I wrote, I die a little inside - embrace the glory of LINQ, and you will be proud of your code!

Upvotes: 1

Related Questions