Swashbuckleを使用して、webapi2プロジェクトのswagger documentation\UIを生成しています。モデルはいくつかのレガシーインターフェイスと共有されているため、モデルで無視したいプロパティがいくつかあります。レガシインターフェイスもJSONにシリアル化する必要があるため、JsonIgnore属性を使用できません。そのため、Swashbuckle構成でプロパティをグローバルに無視したくありません。
私はここで文書化されたこれを行う方法を見つけました:
https://github.com/domaindrivendev/Swashbuckle/issues/7
しかし、これは現在のスワッシュバックルのリリースでは時代遅れのようです。
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>());
しかし、現在のバージョンでIModelFilterを使用するようにSwashbuckleを構成する方法がわかりませんか? Swashbuckle 5.5.3を使用しています。
JsonIgnoreを使用せずにこれを実行する必要がある場合(プロパティのシリアル化/逆シリアル化が必要な場合があります)、カスタム属性を作成します。
[AttributeUsage(AttributeTargets.Property)]
public class SwaggerExcludeAttribute : Attribute
{
}
次に、 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
}
フィルターを登録することを忘れないでください
c.SchemaFilter<SwaggerExcludeFilter>();
フィールド/プロパティにinternal
またはprotected
またはprivate
のマークを付けると、swaggerドキュメントのスワッシュバックルによって自動的に無視されます。
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);
}
}
}
}
さて、少し突っ込んで、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を使用できるかどうかについては、まだ興味があります。
以下のコードは@Richardの回答に非常に基づいていますが、3つのまったく新しい便利な機能が追加されているため、新しい回答として含めています。
SwaggerIgnore
属性を適用できますJsonProperty
属性を使用してプロパティ名とフィールド名がオーバーライドされた可能性があるという事実を処理します改訂されたコードは次のとおりです。
[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);
}
}
}
およびStartup.cs
:
services.AddSwaggerGen(c =>
{
...
c.SchemaFilter<SwaggerIgnoreFilter>();
...
});
Swaggerのドキュメントから除外するプロパティをマークする属性。
[AttributeUsage(AttributeTargets.Property)]
public class SwaggerExcludeAttribute : Attribute
{
}
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);
}
}
}
}
schema.Properties.Keys
はcamelCase
ですが、プロパティ自体はPascalCase
です。両方を小文字に変換し、何を除外すべきかを比較する方法を調整しました。
( ミューテックスの答えに基づく 。)
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;
}
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);
}
}
。Net Coreを使用しており、app.UseSwaggerUi3WithApiExplorer()
のビルドを使用している私のような人々のために
つかいます [JsonIgnore]
タグを使用してNewtonsoft.Json;
public class Project
{
[Required]
public string ProjectName { get; set; }
[JsonIgnore]
public string SomeValueYouWantToIgnore { get; set; }
}
ドキュメントから除外されます。