如何使用Newtonsoft反序列化不同数据类型的JSON Values属性?
解决Newtonsoft反序列化不同DataType对应不同Values类型的问题
方法一:用JObject手动解析(灵活可控)
直接将JSON解析为JObject,根据DataType的值决定Values的解析方式,无需强类型绑定,适合结构不固定的场景。
示例代码:
// 假设JSON结构如下 // { // "Question": "xxx", // "Answer": { // "DataType": "StringList", // 或"ObjectList" // "Values": ["a", "b"] // 或[{"Id":1,"Name":"x"},...] // } // } var jsonStr = File.ReadAllText("yourfile.json"); var jObj = JObject.Parse(jsonStr); var answerJObj = jObj["Answer"]; var dataType = answerJObj["DataType"].ToString(); if (dataType == "StringList") { var stringValues = answerJObj["Values"].ToObject<List<string>>(); // 处理字符串列表逻辑 } else if (dataType == "ObjectList") { var objectValues = answerJObj["Values"].ToObject<List<YourCustomObject>>(); // 处理自定义对象列表逻辑 }
方法二:自定义JsonConverter(强类型友好)
如果需要保持强类型实体类,可编写自定义转换器,反序列化时根据DataType自动匹配Values的类型。
首先定义实体类:
public class QaModel { public string Question { get; set; } public Answer Answer { get; set; } } public class Answer { public string DataType { get; set; } [JsonConverter(typeof(AnswerValuesConverter))] public object Values { get; set; } } public class YourCustomObject { public int Id { get; set; } public string Name { get; set; } }
然后实现自定义转换器:
public class AnswerValuesConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(object); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { var jToken = JToken.Load(reader); // 调整层级确保能获取到Answer节点的DataType var parentNode = jToken.Parent.Parent as JObject; var dataType = parentNode?["DataType"]?.ToString(); if (dataType == "StringList") { return jToken.ToObject<List<string>>(); } else if (dataType == "ObjectList") { return jToken.ToObject<List<YourCustomObject>>(); } return null; } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { serializer.Serialize(writer, value); } }
使用时直接反序列化:
var qaModel = JsonConvert.DeserializeObject<QaModel>(jsonStr); if (qaModel.Answer.DataType == "StringList") { var stringVals = (List<string>)qaModel.Answer.Values; } else if (qaModel.Answer.DataType == "ObjectList") { var objVals = (List<YourCustomObject>)qaModel.Answer.Values; }
方法三:泛型类+条件反序列化
若DataType的类型固定,可定义泛型Answer类,根据DataType选择对应泛型类型反序列化,类型安全性更高。
定义泛型实体类:
public class QaModel<T> { public string Question { get; set; } public Answer<T> Answer { get; set; } } public class Answer<T> { public string DataType { get; set; } public List<T> Values { get; set; } }
反序列化时判断类型:
var jObj = JObject.Parse(jsonStr); var dataType = jObj["Answer"]["DataType"].ToString(); object qaModel; if (dataType == "StringList") { qaModel = jObj.ToObject<QaModel<string>>(); } else if (dataType == "ObjectList") { qaModel = jObj.ToObject<QaModel<YourCustomObject>>(); }
内容的提问来源于stack exchange,提问作者user1801525
相关产品推荐
相关产品推荐

