J'utilise Swashbuckle pour générer la documentation\UI de swagger pour un projet webapi2. Nos modèles étant partagés avec certaines interfaces héritées, 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 au format JSON. Par conséquent, je ne souhaite pas ignorer les propriétés globalement, uniquement dans la configuration Swashbuckle.
J'ai trouvé une méthode de faire ceci documentée ici:
https://github.com/domaindrivendev/Swashbuckle/issues/73
Mais cela semble être obsolète avec la version actuelle de 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 sais pas comment configurer Swashbuckle pour utiliser le filtre IModelFilter dans la version actuelle? J'utilise Swashbuckle 5.5.3.
Si vous devez le faire mais sans utiliser JsonIgnore (vous devez peut-être quand même 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 semblable à 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
}
N'oubliez pas d'enregistrer le filtre
c.SchemaFilter<SwaggerExcludeFilter>();
Si vous marquez un champ/une propriété comme internal
ou protected
ou private
, il sera automatiquement ignoré par swashbuckle dans la documentation swagger.
Eh bien, en cherchant un peu, j'ai trouvé un moyen de faire cela 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 de httpConfiguration.EnableSwagger
, j'ai défini la SwaggerDocsConfig
pour utiliser ce SchemaFilter comme suit:
c.SchemaFilter<ApplyCustomSchemaFilters>();
J'espère que ça aide quelqu'un. Je serais toujours curieux de savoir s'il est possible d'utiliser IModelFilter d'une manière ou d'une autre.
La solution AspNetCore
se présente comme suit:
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);
}
}
}
}
Le code ci-dessous est très basé sur la réponse de @ Richard, mais je l'inclue en tant que nouvelle réponse car il comporte trois nouvelles fonctionnalités utiles que j'ai ajoutées:
SwaggerIgnore
d'être appliqué aux champs et pas seulement aux propriétésJsonProperty
Le code révisé est donc:
[AttributeUsage(AttributeTargets.Field | AttributeTargets.Property)]
public class SwaggerIgnoreAttribute : Attribute
{
}
internal static class StringExtensions
{
internal static string ToCamelCase(this string value)
{
if (string.IsNullOrEmpty(value)) return value;
return char.ToLowerInvariant(value[0]) + value.Substring(1);
}
}
public class SwaggerIgnoreFilter : ISchemaFilter
{
public void Apply(OpenApiSchema schema, SchemaFilterContext schemaFilterContext)
{
if (schema.Properties.Count == 0)
return;
const BindingFlags bindingFlags = BindingFlags.Public |
BindingFlags.NonPublic |
BindingFlags.Instance;
var memberList = schemaFilterContext.SystemType
.GetFields(bindingFlags).Cast<MemberInfo>()
.Concat(schemaFilterContext.SystemType
.GetProperties(bindingFlags));
var excludedList = memberList.Where(m =>
m.GetCustomAttribute<SwaggerIgnoreAttribute>()
!= null)
.Select(m =>
(m.GetCustomAttribute<JsonPropertyAttribute>()
?.PropertyName
?? m.Name.ToCamelCase()));
foreach (var excludedName in excludedList)
{
if (schema.Properties.ContainsKey(excludedName))
schema.Properties.Remove(excludedName);
}
}
}
et en Startup.cs
:
services.AddSwaggerGen(c =>
{
...
c.SchemaFilter<SwaggerIgnoreFilter>();
...
});
Voici ce que j'ai utilisé 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);
}
}
( Basé sur la réponse de mutex .)
J'ai ajouté une autre ligne pour ne pas avoir de 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;
}
Pour les personnes comme moi qui utilisent .Net Core et utilisent le build in app.UseSwaggerUi3WithApiExplorer()
Utilisez la balise [JsonIgnore]
en utilisant Newtonsoft.Json ;
public class Project
{
[Required]
public string ProjectName { get; set; }
[JsonIgnore]
public string SomeValueYouWantToIgnore { get; set; }
}
Il sera exclu de votre documentation.
Basé sur la réponse de Stef Heyenrath.
Attribut pour marquer les propriétés à exclure de la documentation Swagger.
[AttributeUsage(AttributeTargets.Property)]
public class SwaggerExcludeAttribute : Attribute
{
}
Filtre permettant d’exclure les propriétés de la documentation Swagger.
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 (var excludedProperty in excludedProperties)
{
var propertyToRemove =
schema.Properties.Keys.SingleOrDefault(
x => x.ToLower() == excludedProperty.Name.ToLower());
if (propertyToRemove != null)
{
schema.Properties.Remove(propertyToRemove);
}
}
}
}
Le schema.Properties.Keys
est camelCase
, tandis que les propriétés elles-mêmes sont PascalCase
. Tweaked la méthode pour convertir les deux en minuscules et comparer pour voir ce qui devrait être exclu.