Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exclude certain Models from Swashbuckle-generated Swagger Schema in ASP.Net Core OData Project

I am using Swashbuckle to generate the Swagger documentation for my ASP.Net Core 3.1 OData project.

The generation of the controllers' methods is perfect. And it is correctly generating the schema based on the models, except for one thing:

For each Model in the schema, it is also generating an additional [ModelName]IQueryableODataValue entry, as shown in the below screenshot:

swagger doc screenshot

The blue check indicates the model. The model entries circled in red are the superfluous entries that are also being added.

Note it is also generating the Void model, also circled in red.

How do I get the swagger documentation to omit the model entries that I have circled in red? I suspect it has something to do with adding a SchemaFilter. But I can't figure out how to apply it to resolve this issue.

EDIT: @0909EM's comment lead me to do some digging into the SchemaFilter a bit more, and I ended up applying the following SchemaFilter:

using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
using System.Linq;

namespace MyProject.SwaggerConfig
{
    public class RemoveBogusDefinitions : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            foreach (var item in context.SchemaRepository.Schemas.Keys.Where(r => r.EndsWith("ODataValue")))
                context.SchemaRepository.Schemas.Remove(item);

            context.SchemaRepository.Schemas.Remove("Void");
        }
    }
}

It works as long as the LAST schema added to the context is a valid model that I want to keep. The problem is that the above code executes, and then the schema is added to the context. So if the last schema being processed happens to be one that I want to exclude, the above code won't do it.

How do I prevent a schema from being added to the context?

like image 634
Shawn de Wet Avatar asked Jan 21 '20 04:01

Shawn de Wet


3 Answers

I had a buch of these schemas because I had ODataQueryOptions<Invoice> queryOptions as an argument in controller action. I solved it with: options.MapType(typeof(ODataQueryOptions<>), () => new ()); so you should be able to do the same with whatever is generating these for you.

like image 91
jbojcic Avatar answered Oct 18 '22 03:10

jbojcic


I had this same issue...

I tried orellabac's answer which did indeed remove the classes from the schema definition however is caused errors to show up when expanding some API methods.

Not an perfect solution but what I did to get around it was include a custom stylesheet with some CSS to hide the relevant items:

startup.cs

    app.UseSwaggerUI(options =>
    {
        options.InjectStylesheet("/custom.css");
    });

custom.css

[id*="ODataValue"], #model-Void {
    display: none;
}

Obviously it will still be there in the swagger.json and the HTML is still there, but for someone looking at the swagger UI it certainly aids clarity.

like image 22
Jon Ryan Avatar answered Oct 18 '22 05:10

Jon Ryan


In my case only this worked:

internal class SwaggerSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        var keys = new System.Collections.Generic.List<string>();
        var prefix = "My.Namespace";
        foreach(var key in context.SchemaRepository.Schemas.Keys)
        {
            if (key.StartsWith(prefix))
            {
                keys.Add(key);
            }
        }
        foreach(var key in keys)
        {
            context.SchemaRepository.Schemas.Remove(key);
        }
    }
}
like image 8
orellabac Avatar answered Oct 18 '22 05:10

orellabac