user11826621
user11826621

Reputation: 11

Hide Model Property from being documented in Swagger

I have properties I don't want to expose in swagger UI but still allow them to be deserialized if they are passed to the controller. Json ignore does not work as it still appears in swagger and does not allow the serialize and deserialze of the property.

I have created an exclude attribute, and applied it to the property, created a schema filter and added it the startup. But the property still appears in swagger.

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

Added to property:

 [SwaggerExcludeAttribute]
 public int? ContentType { get; set; }

Filter:

 public class SwaggerExcludeSchemaFilter : ISchemaFilter
 {
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (schema?.Properties.Count == 0)
        {
            return;
        }
        const BindingFlags bindingFlags = BindingFlags.Public |
                                     BindingFlags.NonPublic |
                                     BindingFlags.Instance;

        var memberList = context.Type
                       .GetFields(bindingFlags).Cast<MemberInfo>()
                       .Concat(context.Type
                       .GetProperties(bindingFlags));
        var excludedList = memberList.Where(m =>
                                       m.GetCustomAttribute<SwaggerExcludeAttribute>()
                                       != null)
                                 .Select(m =>
                                     (m.GetCustomAttribute<JsonPropertyAttribute>()
                                      ?.PropertyName
                                      ?? m.Name.ToCamelCase()));

        foreach (var excludedName in excludedList)
        {
            if (schema.Properties.ContainsKey(excludedName))
                schema.Properties.Remove(excludedName);
        }
        var excludedProperties = context.Type.GetProperties().Where(
            t => t.GetCustomAttribute<SwaggerExcludeAttribute>() != null);

        foreach (var excludedProperty in excludedProperties)
        {
            var propertyToRemove =
                schema.Properties.Keys.SingleOrDefault(
                    x => x.ToLower() == excludedProperty.Name.ToLower());

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

}

in Startup:

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

The contenttype still appears in the swagger document. Does anyone have another suggestion or way to make this happen?

Upvotes: 1

Views: 1939

Answers (1)

Ivan Valadares
Ivan Valadares

Reputation: 949

Use the lastest version : 5.4.1

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

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

            foreach (var excludedProperty in excludedProperties)
            {
                var propertyToRemove = schema.Properties.Keys.SingleOrDefault(x => x.ToLower() == excludedProperty.Name.ToLower());

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

Upvotes: 1

Related Questions