Как настроить Swashbuckle для игнорирования свойства в модели

Я использую Swashbuckle для создания swagger documentationUI для проекта webapi2. Наши модели совместно используются с некоторыми устаревшими интерфейсами, поэтому есть несколько свойств, которые я хочу игнорировать на моделях. Я не могу использовать атрибут JsonIgnore, потому что устаревшие интерфейсы также должны сериализоваться в JSON, поэтому я не хочу игнорировать свойства глобально, только в конфигурации Swashbuckle.

Я нашел способ сделать это документально здесь:

https://github.com/domaindrivendev/Swashbuckle/issues/73

но это, похоже, устарело с текущим выпуском Swashbuckle.

метод, рекомендуемый для старой версии Swashbuckle, использует реализацию IModelFilter следующим образом:

public class OmitIgnoredProperties : IModelFilter
{
    public void Apply(DataType model, DataTypeRegistry dataTypeRegistry, Type type)
    {
        var ignoredProperties = … // use reflection to find any properties on 
                                  // type decorated with the ignore attributes

        foreach (var prop in ignoredProperties) 
            model.Properties.Remove(prop.Name);

    }
}

SwaggerSpecConfig.Customize(c => c.ModelFilter<OmitIgnoredProperties>());

но я не уверен, как настроить Swashbuckle для использования IModelFilter в текущей версии? Я использую Swashbuckle 5.5.3.

6 ответов


Если вам нужно сделать это, но без использования JsonIgnore (возможно, Вам все еще нужно сериализовать/десериализовать свойство), просто создайте пользовательский атрибут.

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

затем фильтр схемы, похожий на Johng это

public class SwaggerExcludeFilter : ISchemaFilter
{
    #region ISchemaFilter Members

    public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
    {
        if (schema?.Properties == null || type == null)
            return;

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

        foreach (var excludedProperty in excludedProperties)
        {
            if (schema.properties.ContainsKey(excludedProperty.Name))
                schema.properties.Remove(excludedProperty.Name);
        }
    }

    #endregion
}

не забудьте зарегистрировать фильтр

c.SchemaFilter<SwaggerExcludeFilter>();

если пометить поле / свойство как internal или protected или private, он будет проигнорирован автоматически swashbuckle в документации swagger.


Ну, с немного тыкать я нашел способ сделать это с помощью ISchemaFilter:

public class ApplyCustomSchemaFilters : ISchemaFilter
{
    public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
    {
        var excludeProperties = new[] {"myProp1", "myProp2", "myProp3"};

        foreach(var prop in excludeProperties)
            if (schema.properties.ContainsKey(prop))
                schema.properties.Remove(prop);
    }
}

затем при вызове httpConfiguration.EnableSwagger Я поставил SwaggerDocsConfig использовать этот SchemaFilter следующим образом:

c.SchemaFilter<ApplyCustomSchemaFilters>();

надеюсь, это кому-то поможет. Мне все равно было бы интересно, можно ли как-то использовать IModelFilter.


вот что я использовал с Newtonsoft.формат JSON.JsonIgnoreAttribute:

internal class ApplySchemaVendorExtensions : Swashbuckle.Swagger.ISchemaFilter
{
    public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
    {
        foreach (var prop in type.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance)
                                 .Where(p => p.GetCustomAttributes(typeof(Newtonsoft.Json.JsonIgnoreAttribute), true)?.Any() == true))
            if (schema?.properties?.ContainsKey(prop.Name) == true)
                schema?.properties?.Remove(prop.Name);
    }
}

(на основе ответа мьютекса.)

я добавил еще одну строку, чтобы не иметь проблем с NullReferenceException.

public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
{
  var excludeProperties = new[] { "myProp1", "myProp2, myProp3"};

   foreach (var prop in excludeProperties)
     if(schema.properties != null) // This line
       if (schema.properties.ContainsKey(prop))
        schema.properties.Remove(prop);        
}

Если вы хотите удалить все схемы

public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
{
  schema.properties = null;       
} 

на AspNetCore решение выглядит так:

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

        var excludedProperties = context.SystemType.GetProperties().Where(t => t.GetCustomAttribute<SwaggerExcludeAttribute>() != null);
        foreach (PropertyInfo excludedProperty in excludedProperties)
        {
            if (schema.Properties.ContainsKey(excludedProperty.Name))
            {
                schema.Properties.Remove(excludedProperty.Name);
            }
        }
    }
}