一尘不染

如何使JSON.NET StringEnumConverter使用连字符分隔的大小写

json

我正在使用一个API,它返回这样的字符串值。 some-enum-value

我尝试将这些值放在一个枚举中,因为默认的StringEnumConverter不能完成工作,因此我尝试使用一些附加逻辑来装饰此Converter。如何确保正确反序列化了这些值?

以下代码是我完成此工作的尝试。然而,reader = new JsonTextReader(new StringReader(cleaned));由于base.ReadJson无法将字符串识别为JSON,所以这行打破了整个事情。

是否有更好的方法可以执行此操作而不必在StringEnumConverter中实现所有现有逻辑?如何解决我的方法?

public class BkStringEnumConverter : StringEnumConverter
{
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.String)
        {
            var enumString = reader.Value.ToString();
            if (enumString.Contains("-"))
            {
                var cleaned = enumString.Split('-').Select(FirstToUpper).Aggregate((a, b) => a + b);
                reader = new JsonTextReader(new StringReader(cleaned));
            }
        }
        return base.ReadJson(reader, objectType, existingValue, serializer);
    }

    private static string FirstToUpper(string input)
    {
        var firstLetter = input.ToCharArray().First().ToString().ToUpper();
        return string.IsNullOrEmpty(input)
            ? input
            : firstLetter + string.Join("", input.ToCharArray().Skip(1));
    }
}

阅读 247

收藏
2020-07-27

共1个答案

一尘不染

我通过在枚举值上添加EnumMember属性解决了该问题。Json.NET的默认值StringEnumConverter完美地处理了这些属性。

例:

public enum MyEnum
{
    [EnumMember(Value = "some-enum-value")]
    SomeEnumValue,
    Value,
    [EnumMember(Value = "some-other-value")]
    SomeOtherValue
}

请注意,您只需要指定属性即可,例如破折号或其他不能在枚举中使用的特殊字符。大写小写由来处理StringEnumConverter。因此,如果服务返回一个类似的值someenumvalue,则应在枚举中像这样使用它Someenumvalue。如果愿意SomeEnumValue,可以使用该EnumMember属性。万一服务以这种方式返回它,someEnumValue您就可以这样使用它SomeEnumValue(当您使用CamelCaseText属性时,它是开箱即用的)。

您可以在中轻松指定转换器和其他设置JsonSerializerSettings

这是我自己使用的设置的示例。

new JsonSerializerSettings
{
    ContractResolver = new CamelCasePropertyNamesContractResolver(),
    Converters = new List<JsonConverter> { new StringEnumConverter { CamelCaseText = true } },
    NullValueHandling = NullValueHandling.Ignore
};
2020-07-27