如何配置swashbuckle以忽略模型上的属性

发布于 2025-02-08 12:38:42 字数 1095 浏览 3 评论 0 原文

我正在使用swashbuckle为WebAPI2项目生成Swagger Document \ UI。我们的模型与一些旧接口共享,因此我想在模型上忽略一些属性。我不能使用jsonignore属性,因为旧的接口也需要序列化与JSON序列化,因此我不想在Swashbuckle配置中忽略全球属性。

我找到了在此处记录的方法:

https://github.com/github.com/domaindrivendevendev/swashbuckle/swashbuckle/sissues/sissues/sissues/sissues/issues /73

但这似乎与当前的swashbuckle版本过时。

推荐用于旧版本的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>());

但是我不确定如何在当前版本中配置Swashbuckle来使用Imodelfilter?我正在使用Swashbuckle 5.5.3。

I'm using Swashbuckle to generate swagger documentation\UI for a webapi2 project. Our models are shared with some legacy interfaces so there are a couple of properties I want to ignore on the models. I can't use JsonIgnore attribute because the legacy interfaces also need to serialize to JSON so I don't want to ignore the properties globally, just in the Swashbuckle configuration.

I found a method of doing this documented here:

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

But this appears to be out of date with the current Swashbuckle release.

The method recommended for the old version of Swashbuckle is using an IModelFilter implementation as follows:

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

But I'm unsure how to configure Swashbuckle to use the IModelFilter in the current version? I'm using Swashbuckle 5.5.3.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(25

二智少女猫性小仙女 2025-02-15 12:38:42

如果您需要执行此操作,但不使用JSONIGNORE(也许您仍然需要序列化/对属性进行序列化),那么只需创建一个自定义属性即可。

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

然后,一个类似于 johng

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

If you need to do this but without using JsonIgnore (maybe you still need to serialize/deserialize the property) then just create a custom attribute.

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

Then a schema filter similar to 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
}

Don't forget to register the filter

c.SchemaFilter<SwaggerExcludeFilter>();
枕花眠 2025-02-15 12:38:42

.net Core 3.1 .NET标准2.1 的解决方案:

使用 JSONIGNORE 来自 Sytem.text.json.json.serialization 名称空间。

jsonignore newtonsoft.json 将无效)

public class Test
{
    [System.Text.Json.Serialization.JsonIgnore]
    public int HiddenProperty { get; set; }
    public int VisibleProperty { get; set; }
}

Solution for .NET Core 3.1 and .NET Standard 2.1:

Use JsonIgnore from System.Text.Json.Serialization namespace.

( JsonIgnore from Newtonsoft.Json will NOT work )

public class Test
{
    [System.Text.Json.Serialization.JsonIgnore]
    public int HiddenProperty { get; set; }
    public int VisibleProperty { get; set; }
}
倒带 2025-02-15 12:38:42

如果将字段/属性标记为内部受保护 private ,则在Swagger Document中会自动忽略它。


更新:显然,这些属性/字段不会在请求/响应中填充。

If you mark field/property as internal or protected or private, it will be ignored automatically by swashbuckle in swagger documentation.

Update: Obviously, those properties/fields won't be populated in request/response.

月野兔 2025-02-15 12:38:42

下面的代码非常基于 @Richard的答案,但我将其作为新答案包括在内,因为它具有三个全新的,有用的功能,我添加了:

  • 在最新版本的Swashbuckle(V5)
  • 允许的 .NET Core上运行。 swaggerignore 要应用于字段的属性不仅要
  • 处理属性和字段名称可能已使用 jsonproperty 属性>属性>属性>
  • 属性编辑:现在正确处理最初的摄影作品。基于滴定的字段或属性(由 @mattruma的答案提示),

因此修订的代码为:

[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 // In v5.3.3+ use Type instead
                            .GetFields(bindingFlags).Cast<MemberInfo>()
                            .Concat(schemaFilterContext.SystemType // In v5.3.3+ use Type instead
                            .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);
        }
    }
}

in startup.cs

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

The code below is very much based on @Richard's answer, but I am including it as a new answer because it has three completely new, useful features which I have added:

  • Runs on .NET Core on the latest version of Swashbuckle (v5)
  • Allows the SwaggerIgnore attribute to be applied to fields not just to properties
  • Handles the fact that property and field names may have been overridden using the JsonProperty attribute
  • EDIT: Now correctly handles camelCasing of originally TitleCased fields or properties (prompted by @mattruma's answer)

So the revised code is:

[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 // In v5.3.3+ use Type instead
                            .GetFields(bindingFlags).Cast<MemberInfo>()
                            .Concat(schemaFilterContext.SystemType // In v5.3.3+ use Type instead
                            .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);
        }
    }
}

and in Startup.cs:

services.AddSwaggerGen(c =>
{
    ...
    c.SchemaFilter<SwaggerIgnoreFilter>();
    ...
});
生活了然无味 2025-02-15 12:38:42

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

The AspNetCore solution looks like:

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);
            }
        }
    }
}
娇妻 2025-02-15 12:38:42

对于像我这样使用 .net core并在 app.useswaggerui3withapiexplorer()中使用构建的人(

使用 [jsonignore] 使用 newtonsoft.json ;

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

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

它将被排除在您的文档之外。

For people like me who are using .Net Core and are using the build in app.UseSwaggerUi3WithApiExplorer()

Use [JsonIgnore] tag using Newtonsoft.Json;

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

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

It will be excluded from your documentation.

ゝ偶尔ゞ 2025-02-15 12:38:42

好吧,有了一点戳戳,我找到了一种使用iSchemafilter进行操作的方法:

public class ApplyCustomSchemaFilters : ISchemaFilter
{
    public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
    {
        var excludeProperties = new[] {"myProp1", "myProp2"};

        foreach(var prop in excludeProperties)
            if (schema.Properties.ContainsKey(prop))
                schema.Properties.Remove(prop);
    }
}

,当调用 httpConfiguration.enableswagger.enableswagger 我设置了 Swagger> Swaggerdocsconfig

c.SchemaFilter<ApplyCustomSchemaFilters>();

然后 帮助某人。我仍然对是否可以以某种方式使用Imodelfilter感到好奇。

Well, with a bit of poking I found a way to do this using ISchemaFilter:

public class ApplyCustomSchemaFilters : ISchemaFilter
{
    public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
    {
        var excludeProperties = new[] {"myProp1", "myProp2"};

        foreach(var prop in excludeProperties)
            if (schema.Properties.ContainsKey(prop))
                schema.Properties.Remove(prop);
    }
}

then when calling httpConfiguration.EnableSwagger I set the SwaggerDocsConfig to use this SchemaFilter as follows:

c.SchemaFilter<ApplyCustomSchemaFilters>();

Hope this helps someone. I'd still be curious on whether it's possible to use the IModelFilter somehow though.

深海里的那抹蓝 2025-02-15 12:38:42

我在这里有一个使用Dotnetcore 3和Swashbuckle 5的工作示例。我花了几个小时才能将其置于适当的位置,所以我想回到这个线程,这对我有帮助,但没有解决我的问题。

创建一个虚拟自定义属性:

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

创建一个Swagger将使用它来生成API模型架构,

public class SwaggerExcludeFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (!(context.ApiModel is ApiObject))
        {
            return;
        }

        var model = context.ApiModel as ApiObject;

        if (schema?.Properties == null || model?.ApiProperties == null)
        {
            return;
        }
        var excludedProperties = model.Type
                .GetProperties()
                .Where(
                    t => t.GetCustomAttribute<SwaggerExcludeAttribute>() != null
                );

        var excludedSchemaProperties = model.ApiProperties
               .Where(
                    ap => excludedProperties.Any(
                        pi => pi.Name == ap.MemberInfo.Name
                    )
                );

        foreach (var propertyToExclude in excludedSchemaProperties)
        {
            schema.Properties.Remove(propertyToExclude.ApiName);
        }
    }
}

然后在 startup.cs File中将其添加到Swagger Configuration中,

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
    c.SchemaFilter<SwaggerExcludeFilter>();
});

您现在可以在On On On On On On on swagger配置。您想从API模式中排除的属性

public class MyApiModel
{
    [SwaggerExclude]
    public Guid Token { get; set; }

    public int Id { get; set; }

    public string Name { get; set; }
}

I have here a working example with DotNetCore 3 and Swashbuckle 5. It took me a few hours to get it in place so I thought to come back to this thread which helped me but didn't solve my issue.

Create a dummy custom attribute:

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

Create a SchemaFilter which will be used by swagger to generate the API Model Schema

public class SwaggerExcludeFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (!(context.ApiModel is ApiObject))
        {
            return;
        }

        var model = context.ApiModel as ApiObject;

        if (schema?.Properties == null || model?.ApiProperties == null)
        {
            return;
        }
        var excludedProperties = model.Type
                .GetProperties()
                .Where(
                    t => t.GetCustomAttribute<SwaggerExcludeAttribute>() != null
                );

        var excludedSchemaProperties = model.ApiProperties
               .Where(
                    ap => excludedProperties.Any(
                        pi => pi.Name == ap.MemberInfo.Name
                    )
                );

        foreach (var propertyToExclude in excludedSchemaProperties)
        {
            schema.Properties.Remove(propertyToExclude.ApiName);
        }
    }
}

Then, inside the Startup.cs file add this to the swagger configuration

services.AddSwaggerGen(c =>
{
    c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
    c.SchemaFilter<SwaggerExcludeFilter>();
});

You can now use the custom attribute on a property that you want to exclude from the API Mode Shema like this

public class MyApiModel
{
    [SwaggerExclude]
    public Guid Token { get; set; }

    public int Id { get; set; }

    public string Name { get; set; }
}
风柔一江水 2025-02-15 12:38:42

您可以使用 swashbuckle.aspnetcore.annotations 软件包,它允许您标记某些属性仅在输入参数中显示,而有些仅在输出中显示。

例如,如果要在帖子的输入参数中隐藏 alertid ,则只需要通过 [swaggerschema] 来执行此操作

public class Alert
{
    [SwaggerSchema(ReadOnly = true)]
    public string AlertId { get; set; }
    public string Type { get; set; }
}

文档

You can use the Swashbuckle.AspNetCore.Annotations package, it allows you to mark that some properties are only displayed in the input parameters, and some are only displayed in the output.

for example, if you want to hide the AlertId in the input parameter of the post, you just need to do this by the [SwaggerSchema]:

public class Alert
{
    [SwaggerSchema(ReadOnly = true)]
    public string AlertId { get; set; }
    public string Type { get; set; }
}

See more about it in the Documentation

七婞 2025-02-15 12:38:42

基于Stef Heyenrath的答案。

将属性属于标记属性以将其排除在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 comelcase ,而属性本身为 pascalcase 。调整了将转换为较低案例转换并比较的方法,以查看应排除的方法。

Based on Stef Heyenrath's answer.

Attribute to mark properties to exclude from the Swagger documentation.

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

The filter to exclude the properties from the Swagger documentation.

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

The schema.Properties.Keys are camelCase, while the properties themselves are PascalCase. Tweaked the method to convert both to lower case and compare to see what should be excluded.

白色秋天 2025-02-15 12:38:42

Swashbuckle现在对Newtonsoft有所支持。
https://github.com/domaindrivendev/Swashbuckle.AspNetCore#systemtextjson-stj -vs-newtonsoft

dotnet add package --version 5.3.1 Swashbuckle.AspNetCore.Newtonsoft

`services.AddSwaggerGenNewtonsoftSupport(); // explicit opt-in - needs tobe placed after AddSwaggerGen();`

Swashbuckle now has support for Newtonsoft.
https://github.com/domaindrivendev/Swashbuckle.AspNetCore#systemtextjson-stj-vs-newtonsoft

dotnet add package --version 5.3.1 Swashbuckle.AspNetCore.Newtonsoft

`services.AddSwaggerGenNewtonsoftSupport(); // explicit opt-in - needs tobe placed after AddSwaggerGen();`
满意归宿 2025-02-15 12:38:42

这是一个较旧的问题,但此后已经有一个低饮食的中间解决方案可在swashbuckle中使用。

隐藏文档中的遗产属性对阻止这些属性的使用无济于事 - 它只是延迟 Discovery 。毕竟,它们仍然是模型的一部分。实际上,让他们无证件意味着消费者无法知道他们不应该使用它们!

您不应该简单地考虑将它们标记为 [Ompolete]

然后,Swashbuckle将在Swagger.json中将它们标记为弃用。在UI中,这将把它们隐藏在示例值部分中,在模式部分中,它们将显示为灰色,并在名称上击中。

如果您仍然希望它们完全隐藏在文档中,则可以在 swaggergeneratoroptions.ignoreobsoleteproperties = true 中设置。

在最初提出这个问题时,这不是可能的解决方案。 弃用标志是OpenAPI V3的功能,直到2017年才发布。

This is an older question, but an low-effort, intermediate solution has since become available in Swashbuckle.

Hiding legacy properties from documentation doesn't do much to discourage usage of these properties - it just delays discovery. After all, they're still part of the model. In fact, leaving them undocumented means consumers have no way of knowing they shouldn't use them!

Rather than have them go undocumented, you should simply consider marking them [Obsolete].

Swashbuckle will then mark them as deprecated in the swagger.json. In the UI, this will hide them in the Example Value sections, and in the Schema sections, they will show as grayed out with strikethrough on the names.

If you still want them to be completely hidden from the documentation, you can then set in SwaggerGeneratorOptions.IgnoreObsoleteProperties = true.

This was not a possible solution at the time this question was originally asked. The deprecated flag is a feature of OpenAPI v3, which was not released until 2017.

南…巷孤猫 2025-02-15 12:38:42

这是我与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);
    }
}

Here is what I used with 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);
    }
}
乖乖哒 2025-02-15 12:38:42

参考 https://stackoverflow.com/a/58193046/11748401以下代码:

public class SwaggerExcludeFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema model, SchemaFilterContext context)
    {

        var excludeProperties = context.ApiModel.Type?.GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(SwaggerExcludeAttribute)));
        if (excludeProperties != null)
        {
            foreach (var property in excludeProperties)
            {
                // Because swagger uses camel casing
                var propertyName = $"{ToLowerInvariant(property.Name[0])}{property.Name.Substring(1)}";
                if (model.Properties.ContainsKey(propertyName))
                {
                    model.Properties.Remove(propertyName);
                }
            }
        }
    }

}

Referring to https://stackoverflow.com/a/58193046/11748401 answer, for creating a filter you can simply use the following code:

public class SwaggerExcludeFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema model, SchemaFilterContext context)
    {

        var excludeProperties = context.ApiModel.Type?.GetProperties().Where(prop => Attribute.IsDefined(prop, typeof(SwaggerExcludeAttribute)));
        if (excludeProperties != null)
        {
            foreach (var property in excludeProperties)
            {
                // Because swagger uses camel casing
                var propertyName = $"{ToLowerInvariant(property.Name[0])}{property.Name.Substring(1)}";
                if (model.Properties.ContainsKey(propertyName))
                {
                    model.Properties.Remove(propertyName);
                }
            }
        }
    }

}
素罗衫 2025-02-15 12:38:42

(Based on mutex's answer.)

I添加了另一条行以没有 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;       
} 

(Based on mutex's answer.)

I added another line to not have problems with 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);        
}

If you want to delete all schemas

public void Apply(Schema schema, SchemaRegistry schemaRegistry, Type type)
{
  schema.properties = null;       
} 
心意如水 2025-02-15 12:38:42

就我而言,我想保持应用程序层DTOS清洁(没有像JSONINGORE这样的任何注释),但仍然能够在控制器Web API中使用它们。

So, in my Application Layer I have a DTO like this:

public class CreateItemCommand {
     public Guid ContainerId { get; set; }
     public string Name { get; set; }
}

And my API design for creating an item is something like:
POST /containers/{containerId}/items

As the ContainerId is coming from the api route, I don't want the asp.net core trying to bind it into the command DTO and I don't want swashbuckle都没有列出。

So my solution is to inherit the original DTO in the API layer like this:

public class CreateItemCommandMod : CreateItemCommand {
   #pragma warning disable IDE0051
   private new ContainerID { get; }
   #pragma warning restore IDE0051
}

...

[HttpPost("{containerId}/items}")]
public Task Create(
   [FromRoute] Guid containerId,
   [FromBody] CreateItemCommandMod command,
) => useCase.Create(command.Apply(r => r.ContainerId = containerId));
  • The useCase.Create from the ApplicationLayer expects the base class CreateItemCommand.
  • .Apply只是我所做的一种非常简单的扩展方法,它可以轻松地将路由参数值设置为通讯DTO属性。

In my case I wanted to keep my Application Layer DTOs clean (without any annotation like JsonIngore) but still being able to use them in my Controllers Web APIs.

So, in my Application Layer I have a DTO like this:

public class CreateItemCommand {
     public Guid ContainerId { get; set; }
     public string Name { get; set; }
}

And my API design for creating an item is something like:
POST /containers/{containerId}/items

As the ContainerId is coming from the api route, I don't want the asp.net core trying to bind it into the command DTO and I don't want swashbuckle listing it neither.

So my solution is to inherit the original DTO in the API layer like this:

public class CreateItemCommandMod : CreateItemCommand {
   #pragma warning disable IDE0051
   private new ContainerID { get; }
   #pragma warning restore IDE0051
}

...

[HttpPost("{containerId}/items}")]
public Task Create(
   [FromRoute] Guid containerId,
   [FromBody] CreateItemCommandMod command,
) => useCase.Create(command.Apply(r => r.ContainerId = containerId));
  • The useCase.Create from the ApplicationLayer expects the base class CreateItemCommand.
  • .Apply is just a very simple extension method that i've made to easily set the routing parameter value into the correspondent dto property.
昔梦 2025-02-15 12:38:42

非常用户的解决方案@jay Shah,但是如果您使用n'ter架构,则无法从BL获取受保护或私有DAL数据。为了解决这个问题,您可以使用此Prop的ACC修改器作为“受保护的内部”,

public class Test
{
    
    protected internal int HiddenProperty { get; set; }
    
}

您可以从BL但不能访问上述数据,但不能访问PL。或API层。

Very userful solution form @Jay Shah, but if you using N'Tier architecture you can not reach protected or private DAL data from BL. to solve this, you can make this prop's acces modifier as "protected internal"

public class Test
{
    
    protected internal int HiddenProperty { get; set; }
    
}

with this you can access aforementioned data from BL but not PL. or API layer.

谁把谁当真 2025-02-15 12:38:42

我受到使用jsonignore忽略控制器动作模型的属性

我正在使用 .net Core 2.1 swashbuckle.aspnetcore 5.3.1
下面的代码解决了问题。

添加一个新的过滤器

public class SwaggerJsonIgnoreFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var ignoredProperties = context.MethodInfo.GetParameters()
                .SelectMany(p => p.ParameterType.GetProperties()
                .Where(prop => prop.GetCustomAttribute<JsonIgnoreAttribute>() != null))
                .ToList();

            if (!ignoredProperties.Any()) return;

            foreach (var property in ignoredProperties)
            {
                operation.Parameters = operation.Parameters
                    .Where(p => (!p.Name.Equals(property.Name, StringComparison.InvariantCulture)))
                    .ToList();
            }
        }
    }

在startup.cs 中使用过滤器

public void ConfigureServices(IServiceCollection services)
{

......

    services.AddSwaggerGen(options =>
    {
        options.SwaggerDoc("v1", new OpenApiInfo { Title = "CustomApi", Version = "v1" });
        options.OperationFilter<SwaggerJsonIgnoreFilter>();
    });

......

}

I get inspired by the blog of Ignoring properties from controller action model in Swagger using JsonIgnore.

I'm using .net core 2.1 and Swashbuckle.AspNetCore 5.3.1.
The code below solved the problem.

Add a new filter

public class SwaggerJsonIgnoreFilter : IOperationFilter
    {
        public void Apply(OpenApiOperation operation, OperationFilterContext context)
        {
            var ignoredProperties = context.MethodInfo.GetParameters()
                .SelectMany(p => p.ParameterType.GetProperties()
                .Where(prop => prop.GetCustomAttribute<JsonIgnoreAttribute>() != null))
                .ToList();

            if (!ignoredProperties.Any()) return;

            foreach (var property in ignoredProperties)
            {
                operation.Parameters = operation.Parameters
                    .Where(p => (!p.Name.Equals(property.Name, StringComparison.InvariantCulture)))
                    .ToList();
            }
        }
    }

Use the Filter in Startup.cs

public void ConfigureServices(IServiceCollection services)
{

......

    services.AddSwaggerGen(options =>
    {
        options.SwaggerDoc("v1", new OpenApiInfo { Title = "CustomApi", Version = "v1" });
        options.OperationFilter<SwaggerJsonIgnoreFilter>();
    });

......

}

不顾 2025-02-15 12:38:42

属性启用属性注释。

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

过滤以排除用属性注释的所有属性。

public class SwaggerExcludeFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (schema.Properties is null)
        {
            return;
        }

        foreach (var property in context.Type.GetProperties().Where(p => p.GetCustomAttribute<SwaggerExcludeAttribute>() is {}))
        {
            var remove = schema.Properties.Keys.SingleOrDefault(p => p == property.Name);

            if (remove is {})
            {
                _ = schema.Properties.Remove(remove);
            }
        }
    }
}

宣传生成服务中的过滤器注册。

_ = services.AddSwaggerGen(options => options.SchemaFilter<SwaggerExcludeFilter>());

应排除属性的注释。

public class Response
{
    public string Message { get; set; }

    [SwaggerExclude]
    public string? StackTrace { get; set; }
}

Attribute to enable annotation of properties.

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

Filter to exclude all properties annotated with attribute.

public class SwaggerExcludeFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (schema.Properties is null)
        {
            return;
        }

        foreach (var property in context.Type.GetProperties().Where(p => p.GetCustomAttribute<SwaggerExcludeAttribute>() is {}))
        {
            var remove = schema.Properties.Keys.SingleOrDefault(p => p == property.Name);

            if (remove is {})
            {
                _ = schema.Properties.Remove(remove);
            }
        }
    }
}

Filter registration in Swagger generation service.

_ = services.AddSwaggerGen(options => options.SchemaFilter<SwaggerExcludeFilter>());

Annotation on properties that should be excluded.

public class Response
{
    public string Message { get; set; }

    [SwaggerExclude]
    public string? StackTrace { get; set; }
}
红焚 2025-02-15 12:38:42

我需要更多控制权才能删除在其他地方声明的属性,并且无法轻松使用删除属性。

创建的过滤器删除了从我的不包括列表中累积的所有项目:

public class SwaggerExcludeFilter : ISchemaFilter
{
    private static readonly List<string> excludes = new List<string>()
    {
       "StoredProcedureName", "ValidationErrors", "changeTracker",
       "code", "customerId", "IsDebug",
    };

    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (schema?.Properties == null || context == null)
            return;

        // Find all properties by name which need to be removed 
       // and not shown on the swagger spec.
        schema.Properties
              .Where(prp => excludes.Any(exc => string.Equals(exc, prp.Key, StringComparison.OrdinalIgnoreCase)))
              .Select(prExclude => prExclude.Key)
              .ToList()
              .ForEach(key => schema.Properties.Remove(key));    
     }
 }

在启动或program.cs for for for for for for for for for for for for for for for for for you .net 6粉丝。

services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new Info
                    {
                        Version = "2.5",
                        Title = "My Swagger Doc G",
                    });

                    c.SchemaFilter<SwaggerExcludeFilter>();     
                    ...
       

I needed more control to remove properties which were declared elsewhere and couldn't easly use a removal attribute.

The filter created removed all items which it came accross from my excludes list:

public class SwaggerExcludeFilter : ISchemaFilter
{
    private static readonly List<string> excludes = new List<string>()
    {
       "StoredProcedureName", "ValidationErrors", "changeTracker",
       "code", "customerId", "IsDebug",
    };

    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (schema?.Properties == null || context == null)
            return;

        // Find all properties by name which need to be removed 
       // and not shown on the swagger spec.
        schema.Properties
              .Where(prp => excludes.Any(exc => string.Equals(exc, prp.Key, StringComparison.OrdinalIgnoreCase)))
              .Select(prExclude => prExclude.Key)
              .ToList()
              .ForEach(key => schema.Properties.Remove(key));    
     }
 }

In startup or program.cs for you .Net 6 fans.

services.AddSwaggerGen(c =>
                {
                    c.SwaggerDoc("v1", new Info
                    {
                        Version = "2.5",
                        Title = "My Swagger Doc G",
                    });

                    c.SchemaFilter<SwaggerExcludeFilter>();     
                    ...
       
国粹 2025-02-15 12:38:42

我使用的是dotnet core 3.1和swashbuckle 6.3.1,这里是更新版本,具有类似逻辑的更新版本,用于使用 iSchemafilter 来过滤带有自定义属性的属性 swaggerexcludeattribute

public class SwaggerExcludeFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        var type = context.Type;
        if (!schema.Properties.Any() || type == null)
        {
            return;
        }

        var excludedPropertyNames = type
                .GetProperties()
                .Where(
                    t => t.GetCustomAttribute<SwaggerExcludeAttribute>() != null
                ).Select(d => d.Name).ToList();

        if (!excludedPropertyNames.Any())
        {
            return;
        }

        var excludedSchemaPropertyKey = schema.Properties
               .Where(
                    ap => excludedPropertyNames.Any(
                        pn => pn.ToLower() == ap.Key
                    )
                ).Select(ap => ap.Key);

        foreach (var propertyToExclude in excludedSchemaPropertyKey)
        {
            schema.Properties.Remove(propertyToExclude);
        }
    }
}

I'm using dotnet core 3.1 and Swashbuckle 6.3.1, here is updated version with the similar logic for using ISchemaFilter to filter properties marked with customed attribute SwaggerExcludeAttribute

public class SwaggerExcludeFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        var type = context.Type;
        if (!schema.Properties.Any() || type == null)
        {
            return;
        }

        var excludedPropertyNames = type
                .GetProperties()
                .Where(
                    t => t.GetCustomAttribute<SwaggerExcludeAttribute>() != null
                ).Select(d => d.Name).ToList();

        if (!excludedPropertyNames.Any())
        {
            return;
        }

        var excludedSchemaPropertyKey = schema.Properties
               .Where(
                    ap => excludedPropertyNames.Any(
                        pn => pn.ToLower() == ap.Key
                    )
                ).Select(ap => ap.Key);

        foreach (var propertyToExclude in excludedSchemaPropertyKey)
        {
            schema.Properties.Remove(propertyToExclude);
        }
    }
}
雪花飘飘的天空 2025-02-15 12:38:42

创建的过滤器删除了从我的排除列表中获得的所有项目。

using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace Api.Helpers
{
public class SwaggerExcludeFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (operation.Parameters.Count == 0)
        {
            return;
        }
        var ignoredProperties = new[] { "CacheKey", "CacheTimeSeconds" };
        foreach (var property in ignoredProperties)
        {
            operation.Parameters = operation.Parameters
                .Where(p => (!p.Name.Equals(property, StringComparison.InvariantCulture)))
                .ToList();
        }
    }
}

}

在启动或program.cs for for for you .net 8.0

 c.OperationFilter<SwaggerExcludeFilter>();

The filter created removed all items which it came accross from my excludes list.

using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;
namespace Api.Helpers
{
public class SwaggerExcludeFilter : IOperationFilter
{
    public void Apply(OpenApiOperation operation, OperationFilterContext context)
    {
        if (operation.Parameters.Count == 0)
        {
            return;
        }
        var ignoredProperties = new[] { "CacheKey", "CacheTimeSeconds" };
        foreach (var property in ignoredProperties)
        {
            operation.Parameters = operation.Parameters
                .Where(p => (!p.Name.Equals(property, StringComparison.InvariantCulture)))
                .ToList();
        }
    }
}

}

In startup or program.cs for you .Net 8.0

 c.OperationFilter<SwaggerExcludeFilter>();
葬﹪忆之殇 2025-02-15 12:38:42

现在,我们从swashbuckle.aspnetcore.annotations nuget软件包中获得了[Swaggerignore]属性。工作完美。

请参阅: https://github.com/domaindrivendevendevendevendevendev/swashbuckle.swashbuckle.aspnetcore/pull/pull/pull/pull/pull/pull/pull/pull/pull/pull/pull/pull/2610 < /a>

Now we have [SwaggerIgnore] attribute from Swashbuckle.AspNetCore.Annotations nuget Package. Work`s perfectly.

See: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/pull/2610

枫林﹌晚霞¤ 2025-02-15 12:38:42

最简单的方法:尝试使用要隐藏的字段内部访问操作员。它对我有用。

The simplest way: Try using the internal access operator for the field you want to hide. It worked for me.

毁我热情 2025-02-15 12:38:42

只需删除 {get; set; }
例如,如果您不希望看到ID
将其用作字段:公共字符串ID;
不是作为属性:公共字符串ID {get;放; }

Just remove { get;set; }
for example if you dont want in request to be seen Id
use it as field: public string Id;
not as property: public string Id { get; set; }

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文