从Swagger中排除特定枚举值

zf2sa74q  于 2023-02-04  发布在  其他
关注(0)|答案(4)|浏览(231)

我总是向所有枚举添加一个Uninitialized值,并将其设置为0,以处理反序列化具有从未设置的枚举属性值的对象的情况。

enum MyEnum
{
    Uninitialized = 0,
    MyEnumValue1 = 1,
    MyEnumValue2 = 2,
    MyEnumValue3 = 3,
}

但是,我不希望Uninitialized值显示在我的Swagger文档中。
我尝试过将[JsonIgnore]属性添加到该值,但没有成功。
有人知道怎么做吗?

4jb9z9bj

4jb9z9bj1#

为了防止其他人对此感到困惑,您可以创建一个自定义SchemaFilter,并使用自定义属性填充Enum属性过滤这些枚举值(在本例中:OpenApiIgnoreEnumAttribute)。

public class OpenApiIgnoreEnumSchemaFilter : ISchemaFilter
    {
        public void Apply(OpenApiSchema schema, SchemaFilterContext context)
        {
            if (context.Type.IsEnum)
            {
                var enumOpenApiStrings = new List<IOpenApiAny>();

                foreach (var enumValue in Enum.GetValues(context.Type))
                {
                    var member = context.Type.GetMember(enumValue.ToString())[0];
                    if (!member.GetCustomAttributes<OpenApiIgnoreEnumAttribute>().Any())
                    {
                        enumOpenApiStrings.Add(new OpenApiString(enumValue.ToString()));
                    }
                }

                schema.Enum = enumOpenApiStrings;
            }
        }
    }
public class OpenApiIgnoreEnumAttribute : Attribute
    {
    }
public enum ApplicationRole
    {
        [OpenApiIgnoreEnum]        
        DoNotExpose = 1,        
        ValueA = 2,        
        ValueB = 3,
    }
e4yzc0pl

e4yzc0pl2#

您可以使用IDocumentFilter从规范中删除任何您想要的内容。
一开始可能不太直观,看看他们提供的一些示例:https://github.com/domaindrivendev/Swashbuckle.AspNetCore/search?q=IDocumentFilter
有了它,您就可以更改swagger json规范来删除或注入任何您想要的东西。
现在要小心,你可能会得到一个不兼容的规范,总是检查它对验证程序:https://validator.swagger.io/validator/debug?url=http://swagger-net-test.azurewebsites.net/swagger/docs/V1

pod7payv

pod7payv3#

您可以简单地省略Uninitialized枚举值来解决这个问题。
枚举实际上可以包含除显式定义之外的值,我可以执行var myEnumValue = (MyEnum)12345;,它不会中断或抛出异常,但它也不会匹配任何显式定义的枚举值。
只要定义的值不等于default(int),或者不等于您选择的枚举类型的默认值,您仍然可以按预期使用枚举,并捕获带有switch default大小写的未初始化值。
这样做的额外好处是捕获 * 所有 * 未列出的枚举值,而不仅仅是显式声明的枚举值。

dvtswwa3

dvtswwa34#

Royston46的回答非常好,并且帮助建立了一个基础,但是我必须做一些修改,使它完全适合我的场景。
第一个问题是处理可为null的类型。如果与枚举关联的基础属性可为null,则context.type.isEnum将返回false。
第二个问题是,当你有多个枚举具有相同的值时,通过值查找成员来检查自定义属性将无法正常工作。在我们的例子中,我们反对使用一些旧的枚举名称,但是为了与现有的API使用者兼容,将它们保留在枚举中。然而,我们需要文档来只显示新名称。
下面是我们根据Royston46的优秀答案构建的修改后的实现:

public class OpenApiIgnoreEnumSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.Type.IsEnum || (Nullable.GetUnderlyingType(context.Type)?.IsEnum ?? false))
        {
            var type = context.Type.IsEnum ? context.Type : Nullable.GetUnderlyingType(context.Type);

            var enumOpenApiStrings = new List<IOpenApiAny>();

            foreach (var enumName in Enum.GetNames(type))
            {
                var member = type.GetMember(enumName)[0];
                if (!member.GetCustomAttributes<OpenApiIgnoreEnumAttribute>().Any())
                {
                    enumOpenApiStrings.Add(new OpenApiString(enumName));
                }
            }

            schema.Enum = enumOpenApiStrings;
        }
    }
}

相关问题