使用System.Text.Json序列化含结构体列表的类对象列表时数据丢失怎么办?
解决System.Text.Json序列化时UGs列表为空的问题
问题重现
你的代码结构及逻辑如下:
结构体与类定义:
struct UGData // 注:原代码中结构体名为UGdata(小写d),需统一命名避免类型不匹配 { public int ID; public float curGen; public float nomGen; } internal class PlantData { public float Level { get; set; } public string UGName { get; set; } public List<UGData> UGs { get; set; } }
数据填充逻辑:
List<PlantData> MyData = new List<PlantData>(); for(int i=0; i<n; i++) { PlantData info = new PlantData(); for(int j=0; j<m;j++) { UGData data = new UGData(); // 填充UG数据属性 info.UGs.Add(data); // 填充其他info属性 } MyData.Add(info); }
序列化代码:
string Jsonoutput = JsonSerializer.Serialize(MyData);
序列化后UGs字段为空数组,未保留结构体数据。
核心问题排查与解决
1. 必须初始化UGs列表
List<UGData>是引用类型,默认值为null。原代码中未初始化info.UGs就调用Add方法,要么会抛出空引用异常,要么实际执行时UGs未被正确填充数据。
修复代码:
PlantData info = new PlantData(); info.UGs = new List<UGData>(); // 新增列表初始化步骤
2. 确认UGData字段已赋值
如果UGData的所有字段都是默认值(ID=0、curGen=0.0f、nomGen=0.0f),且序列化时启用了IgnoreDefaultValues配置,这些值会被忽略。若需要保留默认值,需调整序列化选项:
调整序列化配置:
var options = new JsonSerializerOptions { IgnoreDefaultValues = false, // 默认值为false,若手动设为true则改回 WriteIndented = true // 可选,格式化输出便于查看 }; string Jsonoutput = JsonSerializer.Serialize(MyData, options);
同时确保填充数据时,给UGData的字段赋了有效数值,而非仅创建空实例。
3. 统一结构体命名
原代码中结构体名为UGdata(小写d),但PlantData中的列表是List<UGData>(大写D),这会导致编译错误,无法正确添加实例到列表中。
修复: 将结构体名称统一为UGData,保证类型匹配。
4. 检查internal类的序列化权限
PlantData是internal类,System.Text.Json默认允许序列化同一程序集内的internal类型。如果序列化代码与PlantData不在同一程序集,需将PlantData改为public类,或在程序集上添加[JsonSerializable]特性。
可选修复(改为public类):
public class PlantData { public float Level { get; set; } public string UGName { get; set; } public List<UGData> UGs { get; set; } }
验证结果
完成上述修复后,序列化结果应包含完整的UGs数据:
[ { "Level": 10, "UGName": "A", "UGs": [ { "ID": 1, "curGen": 10.5, "nomGen": 20.0 } ] }, { "Level": 30, "UGName": "B", "UGs": [ { "ID": 2, "curGen": 15.0, "nomGen": 25.0 } ] } ]
内容的提问来源于stack exchange,提问作者FelipeFonsecabh
相关产品推荐
相关产品推荐

