2015-08-17 87 views
3

我目前正在使用Json.net在我的應用程序中使用json。 我使用的API給我一個特定的字符串格式枚舉例如:Json.net自定義枚舉轉換器

對於TemperatureType型與價值枚舉fahrenheit, Celcius

JSON的值是: {"result":["TemperatureType_fahrenheit","TemperatureType_Celcius"]}

我會喜歡使用轉換器直接管理它以獲得 和IList<TemperatureType>,但也適用於其他枚舉類型。

有沒有人有想法?

我已經嘗試使用自定義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屬性,因爲我還沒有得到參數指示所需類型和沒有命名空間

+0

1)您的JSON似乎無效。不應該在開頭有'{「'2)這是一個[Howto裝飾JSON.NET StringEnumConverter]的副本(http://stackoverflow.com/questions/22908204/howto-decorate-json-net- stringerum轉換器)? – dbc

+0

它只是我的Json響應的一部分(json包含的值之一) 關於裝飾,我已經看到了線程,但是我不想添加字符串修飾器,以避免開發人員的錯誤 – Tchoupi

回答

7

枚舉類型是objectType參數爲ReadJson。但是,有幾點:

  1. 您需要處理可爲null的枚舉類型。
  2. 您需要處理[Flag]枚舉。 Json.NET將它們寫成逗號分隔的值列表。
  3. 你需要處理一個無效值的枚舉的情況。 JSON.NET在StringEnumConverter.AllowIntegerValues == true中將這些值作爲數值寫入,否則會引發異常。

這裏是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); 
+0

這正是我正在尋找的,現在我更瞭解json轉換器。謝謝! – Tchoupi