2016-12-06 5 views
3

J'utilise Swashbuckle pour générer de la documentation swagger \ UI pour un projet webapi2. Nos modèles sont partagés avec certaines interfaces héritées, donc il y a quelques propriétés que je veux ignorer sur les modèles. Je ne peux pas utiliser l'attribut JsonIgnore car les interfaces héritées doivent également être sérialisées en JSON, donc je ne veux pas ignorer les propriétés globalement, juste dans la configuration Swashbuckle.Comment faire pour configurer Swashbuckle pour ignorer la propriété sur le modèle

J'ai trouvé une méthode de faire ce qui est documenté ici:

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

Mais cela semble être à jour avec la version actuelle Swashbuckle.

La méthode recommandée pour l'ancienne version de Swashbuckle utilise une implémentation IModelFilter comme suit:

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>()); 

Mais je ne suis pas sûr comment configurer Swashbuckle utiliser la IModelFilter dans la version actuelle? J'utilise Swashbuckle 5.5.3.

+0

vous pouvez effectivement utiliser JsonIgno repropety qui ne montrera pas la propriété dans le fanfaron –

+0

Comme mentionné dans la question je ne veux pas utiliser JsonIgnore comme j'ai le code hérité qui doit également utiliser les modèles, et si j'applique JsonIgnore qui affectera swagger et le code hérité ... – mutex

Répondre

4

Eh bien, avec un peu de poking j'ai trouvé une façon de le faire en utilisant 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); 
    } 
} 

puis lors de l'appel httpConfiguration.EnableSwagger je mets le SwaggerDocsConfig d'utiliser cette SchemaFilter comme suit:

c.SchemaFilter<ApplyCustomSchemaFilters>(); 

J'espère que cela aide quelqu'un. Je serais toujours curieux de savoir s'il est possible d'utiliser le IModelFilter d'une manière ou d'une autre.

2

(Based on mutex's answer.)

j'ai ajouté une autre ligne pour ne pas avoir des problèmes avec 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);   
}

Si vous voulez supprimer tous les schémas

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

Voici ce que je avec 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); 
    } 
} 
6

Si vous marquez le terrain/propriété comme interne ou protégé ou privé, il sera automatiquement ignoré par swashbuckle dans la documentation swagger.

+0

Ceci est la meilleure solution IMO – infl3x

1

Si vous avez besoin de le faire mais sans utiliser JsonIgnore (peut-être devez-vous encore sérialiser/désérialiser la propriété), créez simplement un attribut personnalisé.

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

Ensuite, un filtre de schéma similaire à Johng's

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 
} 

Ne pas oublier d'enregistrer le filtre

c.SchemaFilter<SwaggerExcludeFilter>(); 
+0

Il semble que cela ne fonctionne que pour les modèles de sortie? Lorsque j'applique ce code sur un modèle d'entrée (utilisé par GET), ce modèle n'est pas trouvé? –

0

La solution AspNetCore ressemble à:

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); 
      } 
     } 
    } 
}