2014-11-03 107 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, ",?\"[^\"]+\":[[]]", "");