JSON.NET-反序列化时的自定义枚举处理

Pur*_*ome 0 c# enums json

我们有一个JSON,可以将其反序列化为自定义域模型,一点问题都没有。它包含一个作为自定义枚举的属性:

public enum UserType
{
    President,
    Chump
}
Run Code Online (Sandbox Code Playgroud)

现在,我们更改了枚举类,但仍然需要接受并反序列化到达的任何JSON的先前值。就像我们现在有两个版本的JSON

public enum UserType
{
    President,
    Vice-President,
    Citizen  // Chump maps to Citizen, now.
}
Run Code Online (Sandbox Code Playgroud)

以及json本身。

"userType": "chump"; // needs to map to Citizen

我不确定该怎么做。

这是使用JsonConverter吗?

同样,这是我们用于所有序列化和反序列化的自定义设置。注意:我们将任何枚举序列化为其string描述/值,而不是其int值。

internal static JsonSerializerSettings JsonSerializerSettings => new JsonSerializerSettings
{
    Converters = new JsonConverter[]
    {
        new StringEnumConverter()
    },
    Formatting = Formatting.Indented
};
Run Code Online (Sandbox Code Playgroud)

干杯!

Oma*_*llo 6

在您EnumEnumMember属性中,添加为序列化/反序列化过程指定值的属性。

public enum UserType
{
    President,
    VicePresident,

    [EnumMember(Value = "chump")]
    Citizen  // Chump maps to Citizen, now.
}
Run Code Online (Sandbox Code Playgroud)

该属性userTypeCitizen在您的json userType中等于"Chump"或时"Citizen"

请记住将System.Runtime.Serialization引用添加到您的项目。

编辑

我注意到Value属性的EnumMember属性检查是区分大小写的。因此,"Chump"如果在json中有,则无法使用"chump"。要解决此问题,您可以使用自定义StringEnumConverter

public class UserTypeEnumConverter : StringEnumConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var userTypeType = typeof(UserType);
        if (objectType == userTypeType)
        {
            var value = reader.Value.ToString().ToLower();

            foreach (var item in Enum.GetNames(userTypeType))
            {
                var memberValue = GetEnumMemberValue(userTypeType.GetMember(item)[0]);
                if (memberValue != null && memberValue.ToLower() == value)
                {
                    return Enum.Parse(userTypeType, item);
                }
            }
        }

        return base.ReadJson(reader, objectType, existingValue, serializer);
    }
}

private static string GetEnumMemberValue(MemberInfo memberInfo)
{
    var attributes = memberInfo.GetCustomAttributes(typeof(EnumMemberAttribute), inherit: false);

    if (attributes.Length == 0) return null;

    return ((EnumMemberAttribute)attributes[0]).Value;
}
Run Code Online (Sandbox Code Playgroud)

在上面的代码中,我仅检查EnumMember属性,因为UserType默认情况下已经完成了对成员的不区分大小写的检查StringEnumConvert

请注意,UserType由于检查,此转换器仅对您的枚举有效:

var userTypeType = typeof(UserType);
if (objectType == userTypeType)
{
Run Code Online (Sandbox Code Playgroud)

JsonSerializerSettings初始化替换为:

internal static JsonSerializerSettings JsonSerializerSettings => new JsonSerializerSettings
{
    Converters = new JsonConverter[]
    {
        new UserTypeEnumConverter()
    },
    Formatting = Formatting.Indented
};
Run Code Online (Sandbox Code Playgroud)

我以为Vice-President枚举数VicePresident在中UserType