wake-up-neo.com

So konfigurieren Sie Swashbuckle, um die Eigenschaften des Modells zu ignorieren

Ich verwende Swashbuckle, um Swagger-Dokumentation\UI für ein Webapi2-Projekt zu generieren. Unsere Modelle werden mit einigen älteren Schnittstellen geteilt, daher gibt es einige Eigenschaften, die ich bei den Modellen ignorieren möchte. Ich kann das JsonIgnore-Attribut nicht verwenden, da die älteren Schnittstellen ebenfalls in JSON serialisiert werden müssen, sodass ich die Eigenschaften nicht global ignorieren möchte, nur in der Swashbuckle-Konfiguration.

Ich habe hier eine dokumentierte Methode gefunden:

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

Dies scheint jedoch mit der aktuellen Version von Swashbuckle nicht mehr aktuell zu sein. 

Die für die alte Version von Swashbuckle empfohlene Methode verwendet eine IModelFilter-Implementierung wie folgt:

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

Aber ich bin nicht sicher, wie man Swashbuckle so konfiguriert, dass der IModelFilter in der aktuellen Version verwendet wird. Ich verwende Swashbuckle 5.5.3. 

18
mutex

Wenn Sie dies tun müssen, ohne JsonIgnore zu verwenden (möglicherweise müssen Sie die Eigenschaft dennoch serialisieren/deserialisieren), erstellen Sie einfach ein benutzerdefiniertes Attribut.

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

Dann ein Schemafilter ähnlich Johngs

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
}

Vergessen Sie nicht, den Filter zu registrieren

c.SchemaFilter<SwaggerExcludeFilter>();
19
Richard

Wenn Sie ein Feld/eine Eigenschaft als internal oder protected oder private markieren, wird dies in der Swagger-Dokumentation automatisch von swashbuckle ignoriert.

13
Jay Shah

Nun, mit ein bisschen Stoßen fand ich einen Weg, dies mit ISchemaFilter zu tun:

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

beim Aufruf von httpConfiguration.EnableSwagger stelle ich SwaggerDocsConfig so ein, dass dieser SchemaFilter wie folgt verwendet wird:

c.SchemaFilter<ApplyCustomSchemaFilters>();

Hoffe das hilft jemandem. Ich wäre immer noch gespannt, ob es möglich ist, den IModelFilter irgendwie zu verwenden.

8
mutex

Die AspNetCore-Lösung sieht folgendermaßen aus:

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);
            }
        }
    }
}
6
Stef Heyenrath

Der folgende Code basiert sehr stark auf der Antwort von @ Richard, aber ich füge ihn als neue Antwort hinzu, weil er drei völlig neue nützliche Funktionen enthält, die ich hinzugefügt habe:

  • Läuft auf .NET Core auf der neuesten Version von Swashbuckle (v5)
  • Ermöglicht die Anwendung des SwaggerIgnore-Attributs auf Felder nicht nur auf Eigenschaften
  • Behandelt die Tatsache, dass Eigenschafts- und Feldnamen möglicherweise mit dem Attribut JsonProperty überschrieben wurden
  • BEARBEITEN: Behandelt das CamelCasing von ursprünglichen TitleCased-Feldern oder -Eigenschaften jetzt korrekt (Aufforderung durch @ mattrumas Antwort)

Der überarbeitete Code lautet also:

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

und in Startup.cs:

services.AddSwaggerGen(c =>
{
    ...
    c.SchemaFilter<SwaggerIgnoreFilter>();
    ...
});
4
Mike Beaton

Folgendes habe ich mit Newtonsoft.Json.JsonIgnoreAttribute verwendet:

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

( Basierend auf der Antwort von mutex .)

Ich habe eine weitere Zeile hinzugefügt, um keine Probleme mit NullReferenceException zu haben.

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

Wenn Sie alle Schemata löschen möchten

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

Für Leute wie mich, die .Net Core verwenden und den Build in app.UseSwaggerUi3WithApiExplorer() verwenden

Verwenden Sie [JsonIgnore]-Tag mit Newtonsoft.Json ;

public class Project
{
    [Required]
    public string ProjectName { get; set; }

    [JsonIgnore]
    public string SomeValueYouWantToIgnore { get; set; }
}

Es wird von Ihrer Dokumentation ausgeschlossen.

2
Jorben Saaltink

Basierend auf Stef Heyenraths Antwort.

Attribut zum Markieren von Eigenschaften, die aus der Swagger-Dokumentation ausgeschlossen werden sollen.

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

Der Filter zum Ausschließen der Eigenschaften aus der Swagger-Dokumentation.

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

Die schema.Properties.Keys sind camelCase, während die Eigenschaften selbst PascalCase sind. Die Methode wurde angepasst, um sowohl in Kleinschreibung als auch im Vergleich zu konvertieren, um zu sehen, was ausgeschlossen werden sollte.

0
mattruma