强制将空JSON数组转换为Dictionary类型

问题是,PHP中的json_encode()函数为正在读取其输出的工具留下了歧义。 在PHP中,列表和字典都是相同类型的array

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

在JSON.NET中,我想强制将[]{"5": "something"}转换为Dictionary类型。 但是它将[]识别为Dictionary的禁止结构并抛出exception。

我可以快速保留空的JSON数组或强制它们转换为空的Dictionary类型吗?

最终解决方案

我修改了接受的答案,使其成为通用的,并可重用于其他类型。

 public class DictionaryOrEmptyArrayConverter : JsonConverter { public override bool CanWrite { get { return false; } } public override bool CanConvert(Type objectType) { return objectType == typeof(Dictionary); } 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(); 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>(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))] public Dictionary upgrades { get; set; } } public class Upgrade { public int level { get; set; } } 

它允许您使用DeserializeObject方法快速将JSON字符串转换为对象:

 var result = JsonConvert.DeserializeObject(jsonString); 

您可以使用自定义JsonConverter来完成它,虽然我认为这个解决方案有点不尽如人意:

  private class DictionaryConverter : JsonConverter { public override bool CanWrite { get { return false; } } public override bool CanConvert(Type objectType) { return objectType == typeof(Dictionary); } 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(); 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 ret = new Dictionary(); 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上的此代码

或者您可以通过删除所有这些空数组属性来预处理json文本。

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