0

ServiceStack v 3.9.71 とServiceStack.Text.EnumMemberSerializerアセンブリを使用して、列挙型を読み取り可能なテキストにシリアル化しています。

これはうまく機能し、列挙型の値は、 を使用して指定した名前にシリアル化されますEnumMemberAttribute

ただし、問題は、Swagger が私の名前を使用しないことです。私の推測では.ToString()、値ではなく列挙値でメソッドを呼び出すだけEnumMemberAttributeです。

シリアライゼーションを設定する順序は次のとおりです。(AppHost 内):

new EnumSerializerConfigurator()
            .WithEnumTypes(new Type[] { typeof(MyEnum) })
            .Configure();

Plugins.Add(new SwaggerFeature());

Swagger 機能が追加される前または後に enum シリアライザーが設定されているかどうかは問題ではないようです。

4

3 に答える 3

2

Swagger コードが列挙値を解析するときに ServiceStack.Text.EnumMemberSerializer を使用しないことは正しいです。Enum.GetValues hereのみを使用します。これは v4 でも同じであることに注意してください。

この変更を行うためにプル リクエストを送信できますが、私は EnumMemberSerialzer と、それが列挙型オプションのリストを取得する方法に精通していません。代わりに、 ApiAllowableValuesで装飾された文字列プロパティを使用して効果を得ることができる場合があります。

于 2014-04-25T13:50:51.837 に答える
1

私の意見では、より良い解決策を思いつきました。を拡張するクラスを作成しました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 のドキュメントが壊れることを心配する必要もなくなりました。

于 2014-05-14T18:58:17.990 に答える
1

これが私が思いついた解決策です(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 のドキュメントが正しくなりました。これに関する唯一の問題は、名前が 2 つの異なる場所にあることです。おそらく、単体テストを介して名前の一致を確認する方法があります。

于 2014-05-07T18:56:15.110 に答える