Exclude certain properties from the Swagger UI

The problem

Sometimes you have some properties on your request model that you don't want to show in the Swagger UI, for whatever reason.

The solution

I'm using Swashbuckle 5.0.
Start by creating the following attribute.
SwaggerIgnorePropertyAttribute.cs

[AttributeUsage(AttributeTargets.Property)]
public class SwaggerIgnorePropertyAttribute : Attribute
{
}

Next, we need to create a new SchemaFilter. It will get all properties for the given type from the SchemaFilterContext, only selecting the ones with the SwaggerIgnorePropertyAttribute.

SwaggerExcludePropertySchemaFilter.cs

public class SwaggerExcludePropertySchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (schema?.Properties == null)
        {
            return;
        }

        var excludedProperties = context.Type.GetProperties().Where(t => t.GetCustomAttribute<SwaggerIgnorePropertyAttribute>() != null);

        foreach (var excludedProperty in excludedProperties)
        {
            var propertyToRemove = schema.Properties.Keys.SingleOrDefault(x => string.Equals(x, excludedProperty.Name, StringComparison.OrdinalIgnoreCase));

            if (propertyToRemove != null)
            {
                schema.Properties.Remove(propertyToRemove);
            }
        }
    }
}

Then we need to register the SchemaFilter like this:

services.AddSwaggerGen(c =>
{
    .....
    c.SchemaFilter<SwaggerExcludePropertySchemaFilter>();
    ....
}

Demo

Given the following OrderInput, the Swagger UI will show two properties, Name and Optional (really good name, right?).

public class OrderInput
{
    public string Name { get; set; }
    public IDictionary<string, object> Optional { get; set; }   
}

orders-before

We wan't to hide the Optional property so we add the SwaggerIgnoreProperty attribute like this...

public class OrderInput
{
    public string Name { get; set; }
    [SwaggerIgnoreProperty]
    public IDictionary<string, object> Optional { get; set; }   
}

orders-after

...and now it does not show up anymore.

This solution is inspired by this answer by Richard on Stack Overflow. I've updated it to work with the latest Swashbuckle release.