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.
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>();
Wenn Sie ein Feld/eine Eigenschaft als internal
oder protected
oder private
markieren, wird dies in der Swagger-Dokumentation automatisch von swashbuckle ignoriert.
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.
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);
}
}
}
}
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:
SwaggerIgnore
-Attributs auf Felder nicht nur auf EigenschaftenJsonProperty
überschrieben wurdenDer ü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>();
...
});
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);
}
}
( 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.
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.