Json.net自定义枚举转换器

我目前正在使用Json.net在我的应用程序中使用json。 我使用的API为枚举发送了一个特定的字符串格式,例如:

对于类型为TemperatureType的枚举,值为fahrenheit, Celcius

json值为: {"result":["TemperatureType_fahrenheit","TemperatureType_Celcius"]}

我想使用转换器直接管理它以获得IList但也适用于其他枚举类型。

有人有想法吗?

我尝试使用自定义JsonConverter:

  if (reader.TokenType == JsonToken.String && reader.Value != null) { string value = reader.Value.ToString(); var splitValues = value.Split('_'); if (splitValues.Length == 2) { var type = Type.GetType(splitValues[0]); return Enum.Parse(type, splitValues[1]); } } 

问题是GetType属性,因为我没有指示所需类型和没有命名空间的参数

枚举类型是ReadJsonobjectType参数。 但是,有几点:

  1. 您需要处理可为空的枚举类型。
  2. 您需要处理[Flag]枚举。 Json.NET将这些写为以逗号分隔的值列表。
  3. 您需要处理具有无效值的枚举的大小写。 当StringEnumConverter.AllowIntegerValues == true时,Json.NET将这些值写为数值,否则抛出exception。

这是StringEnumConverter的子类,它通过调用基类然后在适当时添加或删除类型前缀来处理这些情况:

 public class TypePrefixEnumConverter : StringEnumConverter { public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { bool isNullable = (Nullable.GetUnderlyingType(objectType) != null); Type enumType = (Nullable.GetUnderlyingType(objectType) ?? objectType); if (!enumType.IsEnum) throw new JsonSerializationException(string.Format("type {0} is not a enum type", enumType.FullName)); var prefix = enumType.Name + "_"; if (reader.TokenType == JsonToken.Null) { if (!isNullable) throw new JsonSerializationException(); return null; } // Strip the prefix from the enum components (if any). var token = JToken.Load(reader); if (token.Type == JTokenType.String) { token = (JValue)string.Join(", ", token.ToString().Split(',').Select(s => s.Trim()).Select(s => s.StartsWith(prefix) ? s.Substring(prefix.Length) : s).ToArray()); } using (var subReader = token.CreateReader()) { while (subReader.TokenType == JsonToken.None) subReader.Read(); return base.ReadJson(subReader, objectType, existingValue, serializer); // Use base class to convert } } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { var array = new JArray(); using (var tempWriter = array.CreateWriter()) base.WriteJson(tempWriter, value, serializer); var token = array.Single(); if (token.Type == JTokenType.String && value != null) { var enumType = value.GetType(); var prefix = enumType.Name + "_"; token = (JValue)string.Join(", ", token.ToString().Split(',').Select(s => s.Trim()).Select(s => (!char.IsNumber(s[0]) && s[0] != '-') ? prefix + s : s).ToArray()); } token.WriteTo(writer); } } 

然后,您可以在任何可以使用StringEnumConverter地方使用它,例如:

  var settings = new JsonSerializerSettings { Converters = new JsonConverter[] { new TypePrefixEnumConverter() } }; var json = JsonConvert.SerializeObject(myClass, Formatting.Indented, settings);