Mar*_*rco 37 c# enums json json.net
我正在使用一个api,它返回这样的字符串值. some-enum-value
我尝试将这些值放在枚举中,因为默认的StringEnumConverter不能完成这项工作,我尝试用一些额外的逻辑来装饰这个转换器.如何确保正确反序列化值?
以下代码是我尝试完成这项工作.然而,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));
    }
}
Mar*_*rco 65
我通过在枚举值上添加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
};
A-S*_*ani 30
您也可以使用此代码:
[JsonConverter(typeof(StringEnumConverter))]
public enum ResposeStatus
{
    [EnumMember(Value = "success value")]
    Success,
    [EnumMember(Value = "fail value")]
    Fail,
    [EnumMember(Value = "error value")]
    Error
};
序列化时JsonConvert.Serialize(),会使用里面的文字EnumMember.
dbc*_*dbc 10
在 Json.NET 12.0.1 中,通过添加NamingStrategyto使这变得更容易StringEnumConverter:
新功能 - 为 StringEnumConverter 添加了对 NamingStrategy 的支持
并且 Json.NET 12.0.3添加了KebabCaseNamingStrategy以连字符分隔的烤肉串外壳,例如some-enum-value:
新功能 - 添加了 KebabCaseNamingStrategy
MyEnum这种方法根本不需要注释。
具体而言,在12.0.3及更高版本,你可以通过KebabCaseNamingStrategy到任何的几个的构造函数的StringEnumConverter构造和添加转换器时JsonSerializerSettings.Converters:
var settings = new JsonSerializerSettings
{
    Converters = { new StringEnumConverter(new KebabCaseNamingStrategy()) },
};
var json = JsonConvert.SerializeObject(MyEnum.SomeEnumValue, settings);
Assert.IsTrue(json == "\"some-enum-value\""); // Passes successfully
这样做后,您的序列化枚举值现在将是 kebab-cased。演示小提琴 #1在这里。
在 Json.NET 12.0.1 和 12.0.2 中,您可以通过子类化来定义自己的烤肉串命名策略SnakeCaseNamingStrategy:
public class KebabCaseNamingStrategy : SnakeCaseNamingStrategy
{
    protected override string ResolvePropertyName(string name)
    {
        return base.ResolvePropertyName(name).Replace('_', '-');
    }
}
演示小提琴 #2在这里。
| 归档时间: | 
 | 
| 查看次数: | 31190 次 | 
| 最近记录: |