OhWelp
OhWelp

Reputation: 207

How to exclude certain model from Swagger UI

I have a model that's being used by one of the other models, that is being accepted as a parameter to one of my controllers. So as a result, this model is being displayed in Swagger UI. This model is a nullable type and is optional and I want to hide it from my documentation.

public class A 
{
    public string SomeProperty { get; set; }
    public B? ClassB {get; set; }
}

public class B 
{
    public int SomeIntProperty { get; set; }
    public bool SomeBooleanProperty { get; set; }
}

in the controller method:

    public async Task<ActionResult<SomeType>> GetSomeType(A modelA, CancellationToken token)

As is, this endpoint will accept a JSON document like:

{
     "SomeProperty": "SomeValue"
}

And won't need B to be present. So as a result, I want to hide B from my Swagger schemas. How can I do that? I found some related questions/answers but all of them are about hiding properties, https://stackoverflow.com/a/48454933/16749442

Hiding all properties of a model results in empty model:

EmptyModel

Upvotes: 2

Views: 4321

Answers (1)

OhWelp
OhWelp

Reputation: 207

The only working and clean solution I found is, unfortunately, using reflection again.

SwaggerExcludeAttribute.cs

[AttributeUsage(AttributeTargets.Class)]
public class SwaggerExcludeAttribute : Attribute
{
}

SwaggerIgnoreModelFilter.cs

public class SwaggerIgnoreModelFilter : IDocumentFilter
{
    public void Apply(OpenApiDocument swaggerDoc, DocumentFilterContext context)
    {
        // Get all models that are decorated with SwaggerExcludeAttribute
        // This will only work for models that are under current Assembly
        var excludedTypes = GetTypesWithHelpAttribute(Assembly.GetExecutingAssembly());
        // Loop through them
        foreach (var _type in excludedTypes)
        {
            // Check if that type exists in SchemaRepository
            if (context.SchemaRepository.TryLookupByType(_type, out _))
            {
                // If the type exists in SchemaRepository, check if name exists in the dictionary
                if (swaggerDoc.Components.Schemas.ContainsKey(_type.Name))
                {
                    // Remove the schema
                    swaggerDoc.Components.Schemas.Remove(_type.Name);
                }
            }
        }
    }

    // Get all types in assembly that contains SwaggerExcludeAttribute
    public static IEnumerable<Type> GetTypesWithHelpAttribute(Assembly assembly)
    {
        return assembly.GetTypes().Where(type => type.GetCustomAttributes(typeof(SwaggerExcludeAttribute), true).Length > 0);
    }
}

Startup.cs

services.AddSwaggerGen(c =>
{
    .....
    c.DocumentFilter<SwaggerIgnoreModelFilter>();
    ......
});

Upvotes: 5

Related Questions