Swashbuckle - 将字符串视为枚举在 Swagger 文档中。

3
我正在使用FluentValidation,希望只从流畅验证器中接收我的自定义错误。这就是为什么我请求类中的所有属性都是字符串的原因。但是,我也希望枚举类型有更好的文档说明。
以下是我的示例请求:
 public class AddNewPaymentRequest
 {
     [EnumDataType(typeof(PaymentStatus))]
     public string PaymentStatus { get; set; }

     public string Id { get; set; }
 }

并且有一个示例枚举:

 public enum PaymentStatus
 {
     Unknown,
     New,
     Pending,
     Completed
 }

控制器:

[HttpPost]
public async Task<ActionResult> PostAsync([FromBody] AddNewPaymentRequest request)
{
   ...
}

我希望这个EnumDataType可以作为Swagger显示枚举描述信息的一种方式,而不是字符串描述。我希望Swagger将此字符串视为枚举。
实际结果: click 期望结果: click 是否有可能以这种方式配置Swashbuckle?

你解决了吗?还是你按照下面的答案做了? - Manish Rawat
不是的,我想尝试使用整数而不是字符串来解决它。 - developer learn999
3个回答

3

我想我们正在谈论 .NET Core

如果您同意,可以将其明确定义为枚举而不是字符串

 public class AddNewPaymentRequest
 {
     //[EnumDataType(typeof(PaymentStatus))]
     //public string PaymentStatus { get; set; }

     public PaymentStatus PaymentStatus { get; set; }

     public string Id { get; set; }
 }

然后,您可以定义SwaggerGen如何处理枚举值

 services.AddSwaggerGen(c => {c.DescribeAllEnumsAsStrings(); } );

如果你在使用Newtonsoft.Json序列化/反序列化枚举类型时,在API接收/发送数据时遇到问题,你可以更加控制转换(如果必要)。

 [Newtonsoft.Json.JsonConverter(typeof(Newtonsoft.Json.Converters.StringEnumConverter))]
 public enum PaymentStatus
 {
     [EnumMember(Value = "Unknwon")]
     Unknown,

     [EnumMember(Value = "New")]
     New,

     [EnumMember(Value = "Pending")]
     Pending,

     [EnumMember(Value = "Completed")]
     Completed,

     [EnumMember(Value = "something_different_with_underline")]
     SomethingDifferentWithUnderline
 }

请注意,这些枚举的 ToString() 方法可能会返回不同的字符串(带有/不带)下划线。

有没有使用INT的方法来实现这个? - developer learn999
2
Swashbuckle的DescribeAllEnumsAsStrings()方法已过时。您应该配置您的序列化程序,Swagger会自动使用它。 - el peregrino
@elperegrino,有.NET6 Minimal API的示例吗? - Kiquenet
1
点击这里查看如何配置JSON序列化器:https://stackoverflow.com/a/55541764/10069673 - undefined

1
Swaggers仅支持RequiredAttributeObsoleteAttributeMetaData(用于外部类)。因此,除了编写以下内容之外,没有其他描述接受值的方法:

/// <summary> 允许的值为....


我们在Swashbuckle中有以下内容吗?https://swagger.io/docs/specification/data-models/enums/ - tnk479
@tnk479 - 我在谈论描述API的C#代码。随后,它将用于生成Swagger文档和OpenApi。 - andrew.fox

0
这些答案都有效地说“你不能这样做,这里有其他选择。” 嗯,你可以这样做,这是如何做的。
创建一个名为OpenApiEnumAttribute的属性,就像这样:
/// <summary>
/// Used in conjunction with OpenApiEnumSchemaFilter to apply the enum property
/// to an OpenAPI schema.
/// </summary>
[AttributeUsage(AttributeTargets.Property)]
public class OpenApiEnumAttribute : Attribute
{
    public OpenApiEnumAttribute(params string[] enumOptions)
    {
        EnumOptions = enumOptions;
    }
    
    public OpenApiEnumAttribute(Type enoom)
    {
        if (!enoom.IsEnum)
        {
            throw new ArgumentException("Type not an enum", nameof(enoom));
        }
        EnumOptions = Enum.GetNames(enoom);
    }
    
    /// <summary>
    /// Options for values that the property can have
    /// </summary>
    public string[] EnumOptions { get; }
}

然后还要创建一个类似这样的模式过滤器:
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.SwaggerGen;

/// <summary>
/// Applies the enum property to an OpenAPI schema. Most useful to constrain
/// strings to be a specific value.
/// </summary>
public class OpenApiEnumSchemaFilter : ISchemaFilter
{
    public void Apply(OpenApiSchema schema, SchemaFilterContext context)
    {
        if (context.MemberInfo == null)
        {
            return;
        }
        var enumAnnotation = context.MemberInfo.GetCustomAttributes(typeof(OpenApiEnumAttribute), false)
            .Cast<OpenApiEnumAttribute>()
            .FirstOrDefault();

        if (enumAnnotation == null) return;

        schema.Enum = enumAnnotation.EnumOptions.Select(option => new OpenApiString(option))
            .Cast<IOpenApiAny>().ToList();
    }
}

最后,在你的 Startup.cs 文件中(或者你调用 AddSwaggerGen 的任何地方):
services.AddSwaggerGen(config => { config.SchemaFilter<OpenApiEnumSchemaFilter>(); } );

根据你的例子,你现在可以这样使用它:
public class AddNewPaymentRequest
{
    [OpenApiEnum(typeof(PaymentStatus))]
    public string PaymentStatus { get; set; }

    public string Id { get; set; }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接