如何使用Newtonsoft反序列化结构不一致的JSON数据?
解决API返回data字段类型不一致的反序列化问题
API返回的JSON中data字段存在两种类型:有时是包含scale和size的对象,有时是纯字符串,直接用固定类型GetData接收会导致Newtonsoft.Json反序列化失败,以下是几种可行的解决办法:
方法一:自定义JsonConverter(推荐)
通过自定义转换器统一处理两种类型的data字段,保证类型安全:
- 实现自定义转换器
public class DataConverter : JsonConverter<GetData> { public override GetData ReadJson(JsonReader reader, Type objectType, GetData existingValue, bool hasExistingValue, JsonSerializer serializer) { // 处理字符串类型的data if (reader.TokenType == JsonToken.String) { // 根据业务需求处理,示例返回null,也可将字符串转为GetData对象 return null; } // 处理对象类型的data else if (reader.TokenType == JsonToken.StartObject) { return serializer.Deserialize<GetData>(reader); } return null; } public override void WriteJson(JsonWriter writer, GetData value, JsonSerializer serializer) { // 序列化时的逻辑,按需实现 serializer.Serialize(writer, value); } }
- 修改
RequestJson类,为Data属性添加转换器特性
public class GetData { public int Scale { get; set; } public int Size { get; set; } } public class RequestJson { public string Name { get; set; } [JsonConverter(typeof(DataConverter))] public GetData Data { get; set; } }
- 保持原有反序列化代码即可
List<RequestJson> requestJson = JsonConvert.DeserializeObject<List<RequestJson>>(json);
方法二:使用JToken灵活处理
将Data字段声明为JToken类型,后续根据实际类型做转换:
- 修改
RequestJson类
public class RequestJson { public string Name { get; set; } public JToken Data { get; set; } }
- 反序列化后判断类型并处理
List<RequestJson> requestJson = JsonConvert.DeserializeObject<List<RequestJson>>(json); foreach (var item in requestJson) { if (item.Data.Type == JTokenType.Object) { GetData getData = item.Data.ToObject<GetData>(); // 处理对象类型的data } else if (item.Data.Type == JTokenType.String) { string strData = item.Data.ToString(); // 处理字符串类型的data } }
方法三:使用dynamic类型(不推荐)
利用动态类型跳过编译时类型检查,但会失去类型安全:
List<dynamic> requestJson = JsonConvert.DeserializeObject<List<dynamic>>(json); foreach (var item in requestJson) { if (item.Data is JObject) { GetData getData = ((JObject)item.Data).ToObject<GetData>(); // 处理对象 } else if (item.Data is string) { string strData = item.Data; // 处理字符串 } }
内容的提问来源于stack exchange,提问作者DannyD
相关产品推荐
相关产品推荐

