2014-11-03 89 views
2

問題是,PHP中的json_encode()函數爲正在讀取其輸出的工具留下了不確定性。在PHP中,這兩個列表和字典都是相同類型的array將空JSON數組強制轉換爲字典類型

echo json_encode([]); // [] 
echo json_encode(["5" => "something"]); // {"5": "something"} 

在JSON.NET我想迫使這兩個[]{"5": "something"}轉換爲Dictionary<string, string>類型。但它將[]識別爲Dictionary的禁止結構並拋出異常。

我可以快速保留空JSON數組爲空還是強制它們轉換爲空字典類型?

最終解決

我修改接受的答案,以使它通用和可重複使用的其他類型。

public class DictionaryOrEmptyArrayConverter<T,F> : JsonConverter 
{ 
    public override bool CanWrite { get { return false; } } 
    public override bool CanConvert(Type objectType) 
    { 
     return objectType == typeof(Dictionary<T, F>); 
    } 
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
    { 
     switch (reader.TokenType) 
     { 
      case JsonToken.StartArray: 
       reader.Read(); 
       if (reader.TokenType == JsonToken.EndArray) 
        return new Dictionary<T, F>(); 
       else 
        throw new JsonSerializationException("Non-empty JSON array does not make a valid Dictionary!"); 
      case JsonToken.Null: 
       return null; 
      case JsonToken.StartObject: 
       var tw = new System.IO.StringWriter(); 
       var writer = new JsonTextWriter(tw); 
       writer.WriteStartObject(); 
       int initialDepth = reader.Depth; 
       while (reader.Read() && reader.Depth > initialDepth) 
       { 
        writer.WriteToken(reader); 
       } 
       writer.WriteEndObject(); 
       writer.Flush(); 
       return JsonConvert.DeserializeObject<Dictionary<T, F>>(tw.ToString()); 
      default: 
       throw new JsonSerializationException("Unexpected token!"); 
     } 
    } 

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
    { 
     throw new NotImplementedException(); 
    } 
} 

你應該和你的JSON對象,用它作爲下面的例子中:

public class Company 
{ 
    public string industry_name { get; set; } 

    [JsonConverter(typeof(DictionaryOrEmptyArrayConverter<int, Upgrade>))] 
    public Dictionary<int, Upgrade> upgrades { get; set; } 
} 

public class Upgrade 
{ 
    public int level { get; set; } 
} 

它可以讓你的JSON字符串快速轉換的對象與DeserializeObject方法:

var result = JsonConvert.DeserializeObject<Company>(jsonString); 

回答

3

你可以用自定義的JsonConverter來做,儘管我認爲這個解決方案有點不盡人意:

private class DictionaryConverter : JsonConverter 
    { 
     public override bool CanWrite { get { return false; } } 
     public override bool CanConvert(Type objectType) 
     { 
      return objectType == typeof(Dictionary<string, string>); 
     } 
     public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) 
     { 
      if (reader.TokenType == JsonToken.StartArray) 
      { 
       reader.Read(); 
       if (reader.TokenType == JsonToken.EndArray) 
        return new Dictionary<string, string>(); 
       else 
        throw new JsonSerializationException("Non-empty JSON array does not make a valid Dictionary!"); 
      } 
      else if (reader.TokenType == JsonToken.Null) 
      { 
       return null; 
      } 
      else if (reader.TokenType == JsonToken.StartObject) 
      { 
       Dictionary<string, string> ret = new Dictionary<string, string>(); 
       reader.Read(); 
       while (reader.TokenType != JsonToken.EndObject) 
       { 
        if (reader.TokenType != JsonToken.PropertyName) 
         throw new JsonSerializationException("Unexpected token!"); 
        string key = (string)reader.Value; 
        reader.Read(); 
        if (reader.TokenType != JsonToken.String) 
         throw new JsonSerializationException("Unexpected token!"); 
        string value = (string)reader.Value; 
        ret.Add(key, value); 
        reader.Read(); 
       } 
       return ret; 
      } 
      else 
      { 
       throw new JsonSerializationException("Unexpected token!"); 
      } 
     } 

     public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
     { 
      throw new NotImplementedException(); 
     } 
    } 

,查看該代碼在https://dotnetfiddle.net/zzlzH4

0

或者你可以通過刪除所有這些空數組屬性預處理JSON文本。

//Will not work with formatted json due to whitespace  
json = Regex.Replace(json, ",?\"[^\"]+\":[[]]", "");