使用JsonConvert.DeserializeObject将指定JSON数组反序列化为自定义TestPoints类时出现反序列化错误的技术咨询
解决JSON数组反序列化为自定义类的问题
嗨,这个报错的原因很明确:你的JSON结构和TestPoints类的结构完全不匹配,Newtonsoft.Json根本不知道怎么把数组里的元素映射到类的两个属性上。咱们一步步来解决:
先搞清楚结构不匹配的点
你的JSON核心结构是这样的:
{ "Info": [ {"Type":{"Value":"pointA"},"X":0.2,"Y":0.22}, {"Type":{"Value":"pointB"},"X":0.3,"Y":0.33} ] }
它的Info字段对应一个数组,每个数组元素包含类型标识和坐标;但你要反序列化的TestPoints是一个包含两个PointF属性的类,这种结构差异直接导致了反序列化失败。
解决方案一:先解析为中间结构,再手动转换
这是最直观的方法,先把JSON解析成和它结构匹配的类,再转成你需要的TestPoints。
步骤1:创建匹配JSON的中间类
首先定义几个和JSON结构完全对应的类:
// 对应JSON里的Type对象 public class TypeInfo { public string Value { get; set; } } // 对应JSON数组里的每个元素 public class PointInfo { public TypeInfo Type { get; set; } public float X { get; set; } public float Y { get; set; } } // 对应整个JSON根对象 public class RootObject { public List<PointInfo> Info { get; set; } }
步骤2:修正你的TestPoints类
注意你原来的属性是默认私有,外部无法赋值,要改成public:
public class TestPoints { public PointF pointA { get; set; } public PointF pointB { get; set; } }
步骤3:解析并转换
先把JSON反序列化成RootObject,再遍历数组给TestPoints赋值:
// 先解析JSON到中间结构 var root = JsonConvert.DeserializeObject<RootObject>(strJson); // 转换为你需要的TestPoints对象 var testPoints = new TestPoints(); foreach (var pointInfo in root.Info) { var point = new PointF(pointInfo.X, pointInfo.Y); switch (pointInfo.Type.Value) { case "pointA": testPoints.pointA = point; break; case "pointB": testPoints.pointB = point; break; // 如果以后有更多点类型,在这里加case即可 } }
解决方案二:自定义JsonConverter(更优雅的方式)
如果不想每次都手动转换,可以写一个自定义转换器,让Newtonsoft.Json直接把JSON转成TestPoints:
步骤1:实现自定义转换器
public class TestPointsConverter : JsonConverter<TestPoints> { public override TestPoints ReadJson(JsonReader reader, Type objectType, TestPoints existingValue, bool hasExistingValue, JsonSerializer serializer) { // 先解析到中间结构 var root = serializer.Deserialize<RootObject>(reader); var testPoints = new TestPoints(); // 赋值逻辑和之前一样 foreach (var pointInfo in root.Info) { var point = new PointF(pointInfo.X, pointInfo.Y); switch (pointInfo.Type.Value) { case "pointA": testPoints.pointA = point; break; case "pointB": testPoints.pointB = point; break; } } return testPoints; } public override void WriteJson(JsonWriter writer, TestPoints value, JsonSerializer serializer) { // 如果需要把TestPoints再序列化成JSON,在这里实现逻辑 var infoList = new List<PointInfo>(); infoList.Add(new PointInfo { Type = new TypeInfo { Value = "pointA" }, X = value.pointA.X, Y = value.pointA.Y }); infoList.Add(new PointInfo { Type = new TypeInfo { Value = "pointB" }, X = value.pointB.X, Y = value.pointB.Y }); serializer.Serialize(writer, new RootObject { Info = infoList }); } }
步骤2:使用转换器反序列化
var settings = new JsonSerializerSettings(); settings.Converters.Add(new TestPointsConverter()); // 现在可以直接反序列化为TestPoints了 var testPoints = JsonConvert.DeserializeObject<TestPoints>(strJson, settings);
这样就能完美解决你的问题啦~
内容的提问来源于stack exchange,提问作者Baldo
相关产品推荐
相关产品推荐

