2

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);
Timothy
  • 41
  • 1
  • 5
  • Why does that order matter to you? swagger-ui has a filter if you want to see something use that: http://swagger-net-test.azurewebsites.net/swagger/ui/index?filter=Res – Helder Sepulveda Apr 29 '20 at 22:49
  • Went to that page. The filter does not filter the "Models" part of the page. The Models section shows the models in the order ScopeResponseModel, Location, Arrays, Data, ... basically a random order. And I think that it is not unreasonable to want to sort a list of items. – Timothy May 01 '20 at 02:22
  • Ohh I see, I never even expand that section ... will try that on my end ... I did noticed that you are on `OpenApiDocument` I wonder if that makes a difference – Helder Sepulveda May 01 '20 at 02:42

2 Answers2

1

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!

Bellarmine Head
  • 3,397
  • 2
  • 22
  • 31
0

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;
        }
    });
})
Kingsley
  • 121
  • 6