Newtonsoft.Json反序列化JSON报错,JavaScriptSerializer可正常解析
问题原因
Newtonsoft.Json 对实现了 IEnumerable<T> 的类型默认会按JSON数组来处理,但你的JSON是一个包含resultSet1属性的JSON对象,序列化器试图将对象转换成集合,因此抛出类型不匹配的错误。而JavaScriptSerializer的逻辑是优先处理类的属性,再兼容枚举接口,所以能正常解析。
解决方案
提供三种可行方案,按需选择:
方案1:移除IEnumerable<Agent>继承(最简)
如果不需要直接将Agents类当作集合遍历,或者可以通过resultSet1属性遍历数据,直接去掉继承即可:
public class Agents { public List<Agent> resultSet1 { get; set; } }
之后正常调用反序列化代码即可:
Agents result = JsonConvert.DeserializeObject<Agents>(responseString);
遍历数据时直接使用result.resultSet1即可。
方案2:添加[JsonObject]特性强制按对象处理
如果必须保留IEnumerable<Agent>继承,在Agents类上添加[JsonObject]特性,强制Newtonsoft.Json将其当作普通对象解析,忽略枚举接口:
[JsonObject] public class Agents : IEnumerable<Agent> { public List<Agent> resultSet1 { get; set; } public IEnumerator<Agent> GetEnumerator() { return ((IEnumerable<Agent>)resultSet1).GetEnumerator(); } IEnumerator IEnumerable.GetEnumerator() { return ((IEnumerable)resultSet1).GetEnumerator(); } }
反序列化代码无需修改,直接使用原有调用即可。
方案3:自定义JsonConverter
如果需要更灵活的序列化/反序列化逻辑,可以编写自定义转换器:
- 实现转换器类:
public class AgentsConverter : JsonConverter<Agents> { public override Agents ReadJson(JsonReader reader, Type objectType, Agents existingValue, bool hasExistingValue, JsonSerializer serializer) { var jObject = JObject.Load(reader); var agents = new Agents(); agents.resultSet1 = jObject["resultSet1"].ToObject<List<Agent>>(serializer); return agents; } public override void WriteJson(JsonWriter writer, Agents value, JsonSerializer serializer) { serializer.Serialize(writer, new { resultSet1 = value.resultSet1 }); } }
- 反序列化时指定转换器:
var settings = new JsonSerializerSettings(); settings.Converters.Add(new AgentsConverter()); Agents result = JsonConvert.DeserializeObject<Agents>(responseString, settings);
或者直接在Agents类上添加特性,省去每次传配置的步骤:
[JsonConverter(typeof(AgentsConverter))] public class Agents : IEnumerable<Agent> { // 类内容不变 }
额外注意
你的JSON字符串中存在一个格式瑕疵:第二个Agent对象末尾多了一个逗号(, ]),虽然部分序列化器可以容忍,但建议修复该问题,避免后续出现其他解析异常。
内容的提问来源于stack exchange,提问作者Muzaffar Mahmood
相关产品推荐
相关产品推荐

