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));
}
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*rco 65
我通过在枚举值上添加EnumMember属性解决了这个问题.Json.NET默认StringEnumConverter
完美地处理这些属性.
例:
public enum MyEnum
{
[EnumMember(Value = "some-enum-value")]
SomeEnumValue,
Value,
[EnumMember(Value = "some-other-value")]
SomeOtherValue
}
Run Code Online (Sandbox Code Playgroud)
请注意,您只需要在破折号或其他特殊字符的情况下指定属性,您不能在枚举中使用.大写的小写由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
};
Run Code Online (Sandbox Code Playgroud)
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
};
Run Code Online (Sandbox Code Playgroud)
序列化时JsonConvert.Serialize()
,会使用里面的文字EnumMember
.
dbc*_*dbc 10
在 Json.NET 12.0.1 中,通过添加NamingStrategy
to使这变得更容易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
Run Code Online (Sandbox Code Playgroud)
这样做后,您的序列化枚举值现在将是 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('_', '-');
}
}
Run Code Online (Sandbox Code Playgroud)
演示小提琴 #2在这里。