[英]Show Enum member friendly name on Swagger dropdown and json
我試圖讓枚舉在 swagger 和響應中顯示來自描述(或任何其他屬性)的友好名稱。 還嘗試解析控制器操作中正文/查詢字符串上設置的友好名稱,而不嘗試 400 BadRequest 或任何類型的驗證錯誤。 我還注意到,我擁有的自定義通用 JsonConverter 也無法正常工作。 ReadJson()
方法根本沒有被調用。 我怎樣才能讓它發揮作用?
[JsonConverter(typeof(JsonEnumConverter<SortDirectionType>))]
public enum SortDirectionType
{
[Description("asc")]
ASCENDING,
[Description("desc")]
DESCENDING
}
我試圖讓 swagger-ui 顯示 asc & desc 作為下拉列表中的值,而不是 ASCENDING & DESCENDING。 這意味着我不能使用c.DescribeAllEnumsAsStrings()
。 如果我不使用它,那么下拉列表會顯示 0,1,因為它應該代表枚舉成員值。 現在我可以使用[EnumMember(Value="asc"]
屬性而不是[Description("asc")]
屬性。但是接下來發生了兩件事:
[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);
}
}
我想出了一個黑客在這里。 它可能不一定是您的解決方案,但是如果您可以使它工作,那么我很高興我可以提供幫助。
最終將枚舉格式更改為字符串而不是默認下拉列表。 這樣我就可以將 asc/desc 值發送到 api。 Swagger 接受了這些值並且沒有拋出驗證錯誤。 我在 .net core api 上編寫的轉換器也能夠很好地轉換它們。
c.MapType<SortDirectionType>(() => new Schema { Type = "string", Format = "string" });
除此之外,您可能還想禁用自動啟動的 asp.net core 2.2 驗證的默認行為。 不知道他們為什么選擇將其設置為默認行為。
services.Configure<ApiBehaviorOptions>(options =>
{
options.SuppressModelStateInvalidFilter = true;
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.