当前位置: 首页 > 知识库问答 >
问题:

在Swagger下拉列表和json上显示枚举成员友好名称

邵兴庆
2023-03-14

我试图让枚举显示友好的名称从描述(或任何其他属性)在招摇和响应。还试图解析的友好名称设置在主体/查询字符串在控制器的行动,而不尝试400 Bad请求或任何类型的验证错误。我还注意到的是,自定义的通用JsonConver我也没有正常工作。ReadJson()方法根本没有被调用。我如何让它工作?

[JsonConverter(typeof(JsonEnumConverter<SortDirectionType>))]
public enum SortDirectionType
{
    [Description("asc")]
    ASCENDING,
    [Description("desc")]
    DESCENDING
}

我正在尝试让swagger-ui显示asc

  1. 要么swagger ui抛出客户端验证,并用红线突出显示字段
  2. 或者,如果我尝试在swagger之外调用endpoint,它会返回400错误
  3. 我能够在action[FromBody]参数中成功使用0,1或ASCENDING、DESCENDING值。然而,这不是预期的。我将接收asc、desc,并希望能够在body模型上成功解析它们,并将其映射到enum属性。另一方面,当json渲染时,它应该渲染友好名称

附加代码:

public class JsonEnumConverter<T> : JsonConverter where T : struct, IComparable, IConvertible, IFormattable
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(T);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var type = typeof(T);

        if (!type.IsEnum) throw new InvalidOperationException();

        var enumDescription = (string)reader.Value;

        return enumDescription.GetEnumValueFromDescription<T>();
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var type = typeof(T);

        if (!type.IsEnum) throw new InvalidOperationException();

        if (value != null)
        {
            if (value is Enum sourceEnum)
            {
                writer.WriteValue(sourceEnum.GetDescriptionFromEnumValue());
            }
        }
    }
}

public static class EnumExtensions
{
    public static string GetDescriptionFromEnumValue(this Enum @enum)
    {
        FieldInfo fi = @enum.GetType().GetField(@enum.ToString());

        DescriptionAttribute[] attributes =
            (DescriptionAttribute[])fi.GetCustomAttributes(
            typeof(DescriptionAttribute),
            false);

        if (attributes != null &&
            attributes.Length > 0)
            return attributes[0].Description;
        else
            return @enum.ToString();
    }

    public static T GetEnumValueFromDescription<T>(this string description)
    {
        var type = typeof(T);

        if (!type.IsEnum)
            throw new InvalidOperationException();

        foreach (var field in type.GetFields())
        {
            if (Attribute.GetCustomAttribute(field,
                typeof(DescriptionAttribute)) is DescriptionAttribute attribute)
            {
                if (attribute.Description == description)
                    return (T)field.GetValue(null);
            }
            else
            {
                if (field.Name == description)
                    return (T)field.GetValue(null);
            }
        }

        throw new ArgumentException($"No matching value for enum {nameof(T)} found from {description}.",$"{nameof(description)}"); // or return default(T);
    }
}

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

共有2个答案

佟云
2023-03-14

我在这里想出了一个窍门。这可能不一定是你的解决方案,但如果你能做到这一点,我很高兴能帮上忙。

最终将枚举格式更改为字符串而不是默认下拉列表。这样我就可以将asc/desc值发送到api。Swagger接受了这些值并且没有抛出验证错误。我在. net核心api上编写的转换器也能够很好地转换它们。

c.MapType<SortDirectionType>(() => new Schema { Type = "string", Format = "string" });

除此之外,您可能还希望禁用自动启动 asp.net 核心 2.2 验证的默认行为。不知道为什么他们选择将其设置为默认行为。

services.Configure<ApiBehaviorOptions>(options =>
{
    options.SuppressModelStateInvalidFilter = true;
});
吴兴国
2023-03-14

这就是为我所做的:

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

我在这里找到了它

 类似资料:
  • 例如: Swagger这样显示枚举: 我想要的是: API返回“显示名称”,然而,Swagger显示“枚举名称”,这经常导致混淆。有可能改变狂妄的价值观吗?

  • 问题内容: 我有一个具有枚举属性的域对象,并且我想以该对象的形式显示一个包含所有可能的枚举值的下拉列表。想象以下对象: 在我的控制器中,我有一个方法呈现此对象的形式: 模板如下所示: 稍后,应将其转换为如下形式: 如何创建选择标签?所选值还应该自动映射到票证,以便我可以在控制器中执行以下操作: 问题答案: 您可以这样做:

  • 我有一个具有枚举属性的域对象,我想在该对象的表单中显示一个包含所有可能枚举值的下拉列表。想象以下对象: 在我的控制器中,我有一个为该对象呈现表单的方法: 模板如下所示: 之后,应将其转换为如下内容: 如何创建select标记?所选值也应自动映射到票证,以便我可以在控制器中执行以下操作:

  • 我有一个应用程序,在JSP页面中,我显示一个下拉列表,但我的代码中有一个例外。 控制器类别:- addDetails.jsp·佩奇 我得到了以下异常:- 它只是一个Spring MVC Web应用程序,我试图在其中显示预先填充了颜色数据的卓尔向下列表。 非常感谢任何帮助。

  • 我正在使用Swashback生成Swagger输出。在我的模型I上,具有以下属性: FieldValue是一个简单的类,可以保存ID和名称: 通过代码中的一些业务逻辑,一组可能的键值对(ID和名称)映射到此属性。 现在,我想在我的Swagger输出中的enum标签中显示所有可能的值。使用ISchemaFilter的一个实现,即MyProperty属性上的一个自定义属性,并使用allOf而不是简单的

  • 我在谷歌工作表中有一个下拉菜单,它引用了不同工作表中的值。 参考表A行值1,B行值1:Value1\u说明值2:Value2\u说明。 在我的工作表中,单元格中有一个下拉菜单,用于设置和显示值1、值2等。 我希望下拉菜单显示参考表Value1:Value1_说明、Value2:Value2_说明等中的显示名称,但仅将Value1 Value2等设置为单元格中的值。 确实如此,但是在谷歌的表单中ht