ServiceStack.Text.EnumMemberSerializer не работает с плагином Swagger
Я использую ServiceStack v 3.9.71 и ServiceStack.Text.EnumMemberSerializer
сборка для сериализации перечислений в читаемый текст.
Это прекрасно работает, мои значения enum сериализуются в имя, которое я указал, используя EnumMemberAttribute
,
Проблема, однако, заключается в том, что Swagger не использует мои имена. Я думаю, это просто вызывает .ToString()
метод на значениях перечисления, а не EnumMemberAttribute
значение.
Вот порядок, в котором я настраиваю сериализацию. (В AppHost):
new EnumSerializerConfigurator()
.WithEnumTypes(new Type[] { typeof(MyEnum) })
.Configure();
Plugins.Add(new SwaggerFeature());
Кажется, не имеет значения, установлен ли сериализатор enum до или после добавления функции чванства.
3 ответа
Я придумал, на мой взгляд, лучшее решение. Я написал класс, который расширяет ApiAllowableValuesAttribute
:
public class ApiAllowableValues2Attribute : ApiAllowableValuesAttribute
{
public ApiAllowableValues2Attribute(string name, Type enumType)
: base(name)
{
List<string> values = new List<string>();
var enumTypeValues = Enum.GetValues(enumType);
// loop through each enum value
foreach (var etValue in enumTypeValues)
{
// get the member in order to get the enumMemberAttribute
var member = enumType.GetMember(
Enum.GetName(enumType, etValue)).First();
// get the enumMember attribute
var enumMemberAttr = member.GetCustomAttributes(
typeof(System.Runtime.Serialization.EnumMemberAttribute), true).First();
// get the enumMember attribute value
var enumMemberValue = ((System.Runtime.Serialization.EnumMemberAttribute)enumMemberAttr).Value;
values.Add(enumMemberValue);
}
Values = values.ToArray();
}
}
Клиентский объект:
public class MyClientObject
{
[Description("The name")]
public string Name {get;set;}
[Description("The client object type")]
[ApiAllowableValues2("MyEnum", typeof(MyEnum))]
public MyEnum MyEnum { get; set; }
}
Теперь вам не нужно снова указывать имена или беспокоиться об изменении имени, что нарушает вашу документацию Swagger.
Вы правы в том, что код Swagger не использует ServiceStack.Text.EnumMemberSerializer при анализе значений перечисления. Он использует только Enum.GetValues
здесь Обратите внимание, что это все то же самое в v4.
Вы можете отправить запрос на выборку, чтобы внести это изменение, но я не знаком с EnumMemberSerialzer и тем, как он позволяет получать список опций перечисления. Вместо этого вы можете использовать строковое свойство, украшенное ApiAllowableValues, для достижения эффекта.
Вот решение, которое я придумал (с помощью bpruitt-goddard, спасибо, приятель):
Перечисление:
public enum MyEnum
{
[EnumMember(Value = "Value One")]
Value1 = 1,
[EnumMember(Value = "Value Two")]
Value2 = 2,
[EnumMember(Value = "Value Three")]
Value3 = 3
}
Клиентский объект:
public class MyClientObject
{
[Description("The name")]
public string Name {get;set;}
[Description("The client object type")]
[ApiAllowableValues("MyEnum", "Value One", "Value Two", "Value Three")]
public MyEnum MyEnum { get; set; }
}
Внутри AppHost:
new EnumSerializerConfigurator()
.WithEnumTypes(new Type[] { typeof(MyEnum) })
.Configure();
Теперь перечисление правильно сериализовано и документация Swagger верна. Единственная проблема с этим - иметь имена в двух разных местах. Возможно, есть способ проверить совпадение имен с помощью юнит-теста.