强制将空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, ",?\"[^\"]+\":[[]]", "");