You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 10:07:42