如何在C#中正确反序列化含对象集合的JSON数据?
问题解决:JSON反序列化失败的原因及修复方案
错误原因分析
你的JSON中results字段是键值对对象(键为"1"、"2"…这类字符串,对应每个地址条目),但C#类jsonAddresses里的results被定义为IList<jsonResults>。Json.NET仅支持将JSON数组([]格式)反序列化为列表/集合类型,因此无法将JSON对象直接转换为IList,触发序列化异常。
修复方案
方案1:修改C#类匹配JSON结构(推荐)
将jsonAddresses中的results类型改为Dictionary<string, jsonResults>,直接对应JSON的键值对结构:
[System.Serializable] public class jsonAddresses { [JsonProperty(PropertyName = "type")] public string type { get; set; } [JsonProperty(PropertyName = "found objects")] public int foundobjects { get; set; } // 建议改为int,JSON中是数字类型 [JsonProperty(PropertyName = "returned objects")] public int returnedobjects { get; set; } // 同上 [JsonProperty(PropertyName = "results")] public Dictionary<string, jsonResults> results { get; set; } // 修改为Dictionary类型 } [System.Serializable] public class jsonResults { [JsonProperty(PropertyName = "city")] public string city { get; set; } [JsonProperty(PropertyName = "citypart")] public string citypart { get; set; } [JsonProperty(PropertyName = "street")] public string street { get; set; } [JsonProperty(PropertyName = "number")] public string number { get; set; } [JsonProperty(PropertyName = "teryt")] public string teryt { get; set; } [JsonProperty(PropertyName = "simc")] public string simc { get; set; } [JsonProperty(PropertyName = "ulic")] public string ulic { get; set; } [JsonProperty(PropertyName = "code")] public string code { get; set; } [JsonProperty(PropertyName = "jednostka")] public string jednostka { get; set; } [JsonProperty(PropertyName = "x")] public string x { get; set; } [JsonProperty(PropertyName = "y")] public string y { get; set; } [JsonProperty(PropertyName = "geometry_wkt")] public string geometry_wkt { get; set; } [JsonProperty(PropertyName = "id")] public int id { get; set; } // 建议改为int,JSON中是数字类型 }
反序列化后若需要列表格式,可直接提取字典的值:
jsonAddresses _jsonAddresses = JsonConvert.DeserializeObject<jsonAddresses>(jsonData); var resultsList = _jsonAddresses.results.Values.ToList();
方案2:自定义JsonConverter将JSON对象转为列表
如果无法修改类结构,可自定义转换器实现JSON对象到列表的转换:
public class ObjectToListConverter<T> : JsonConverter<IList<T>> { public override IList<T> ReadJson(JsonReader reader, Type objectType, IList<T> existingValue, bool hasExistingValue, JsonSerializer serializer) { var obj = JObject.Load(reader); return obj.Properties().Select(p => p.Value.ToObject<T>()).ToList(); } public override void WriteJson(JsonWriter writer, IList<T> value, JsonSerializer serializer) { throw new NotImplementedException(); } }
在jsonAddresses的results字段上添加转换器特性:
[JsonProperty(PropertyName = "results")] [JsonConverter(typeof(ObjectToListConverter<jsonResults>))] public IList<jsonResults> results { get; set; }
这样反序列化时会自动将JSON对象转为列表。
额外注意点
- JSON中的
found objects、returned objects、id均为数字类型,建议将C#类对应字段从string改为int,避免不必要的类型转换。 - 原始JSON中
jednostka字段的字符串存在语法错误(结尾多了引号和右大括号),需确保JSON格式正确,否则会导致该字段反序列化失败。
内容的提问来源于stack exchange,提问作者Piotr Magdziak
相关产品推荐
相关产品推荐

