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

C#使用Newtonsoft.Json将平级x、y属性嵌套为position对象的方案求解

C# 使用Newtonsoft.Json实现平级x/y字段转嵌套position结构解决方案

问题核心

需要将源JSON中平级的x、y属性,转换为目标JSON中嵌套在position下的结构,同时完成其他字段的映射替换。

方案1:手动对象映射(最推荐,可控性最高)

步骤1:修正实体类定义

首先分别定义源JSON反序列化用类和目标JSON序列化用类,不要混用,避免属性冲突:

// 源JSON反序列化专用类
public class SourceRoot
{
    public List<SourceItem> n { get; set; }
}

public class SourceItem
{
    public string type { get; set; }
    public string id { get; set; }
    public int x { get; set; }
    public int y { get; set; }
    public string text { get; set; }
    public string fill { get; set; }
    public string physicalLocation { get; set; }
    public int[] thisInterfaceTypes { get; set; }
    public int[] otherInterfaceTypes { get; set; }
    public string[] link { get; set; }
    public object[] otherLocationEntityIds { get; set; }
    public bool[] shouldUseLegacyLinkTypes { get; set; }
}

// 目标JSON序列化专用类
public class TargetRoot
{
    public List<Cell> cells { get; set; }
}

public class Cell
{
    public string type { get; set; }
    public Size size { get; set; }
    public Position position { get; set; }
    public int angle { get; set; }
    public string id { get; set; }
    public int z { get; set; }
    public Attrs attrs { get; set; }
    // 其他需要的属性自行补充
}

public class Size
{
    public int width { get; set; }
    public int height { get; set; }
}

public class Position
{
    public int x { get; set; }
    public int y { get; set; }
}

// Attrs相关的嵌套类你已经有对应结构的话直接用,没有就按目标JSON定义即可

步骤2:编写映射转换逻辑

// 1. 反序列化源JSON
var sourceJson = "你的源JSON字符串";
var sourceData = JsonConvert.DeserializeObject<SourceRoot>(sourceJson);

// 2. 手动映射到目标结构
var targetData = new TargetRoot
{
    cells = sourceData.n.Select(item => new Cell
    {
        type = "app.Router", // 按你的规则替换type值
        id = item.id, // 直接复用源ID,需要生成新的话自行替换
        position = new Position
        {
            x = item.x, // 直接取源平级x赋值到嵌套position的x
            y = item.y  // 直接取源平级y赋值到嵌套position的y
        },
        size = new Size { width = 90, height = 35 }, // 固定值或者按规则计算
        angle = 0,
        z = 1,
        attrs = new Attrs
        {
            // 你的attrs属性赋值逻辑,比如fill可以取源item.fill的值
        }
        // 其他属性按你的规则赋值
    }).ToList()
};

// 3. 序列化得到目标JSON
var targetJson = JsonConvert.SerializeObject(targetData, Formatting.Indented);

原有代码问题说明

你当前的类中存在多个标注[JsonExtensionData]的属性,Newtonsoft.Json规定一个类只能有一个被该特性标记的属性,多个会导致序列化/反序列化异常,这也是你之前x/y值为null的常见原因之一。

方案2:自定义JsonConverter(适合不想写映射逻辑的场景)

如果需要直接在序列化的时候自动转换,可以自定义转换器:

public class PositionConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var item = (N)value;
        writer.WriteStartObject();
        // 写入其他正常属性
        writer.WritePropertyName("type");
        serializer.Serialize(writer, "app.Router");
        writer.WritePropertyName("id");
        serializer.Serialize(writer, item.entityId);
        // 写入嵌套position
        writer.WritePropertyName("position");
        serializer.Serialize(writer, new { x = item.x, y = item.y });
        // 其他属性按规则写入
        writer.WriteEndObject();
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(N);
    }
}

使用的时候在序列化时传入转换器即可:

var json = JsonConvert.SerializeObject(yourObject, Formatting.Indented, new PositionConverter());

内容的提问来源于stack exchange,提问作者lpierpoint

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 05:27:03