c# - 如何使用 System.Text.Json 序列化/反序列化非枚举类型的嵌套字典?
问题描述
我正在尝试序列化这本字典:
IDictionary<string, ResetableObjectTheme> ResetableObjectThemes = new Dictionary<string, ResetableObjectTheme>()
{
{"ThemeDark", new ResetableObjectTheme() { ResetablePatternObject = new PatternObject(), ResetableMaterialObject = new MaterialObject()}},
{"ThemeLight", new ResetableObjectTheme() { ResetablePatternObject = new PatternObject(), ResetableMaterialObject = new MaterialObject()}},
};
string json = System.Text.Json.JsonSerializer.Serialize(ResetableObjectThemes, new JsonSerializerOptions() { WriteIndented = true });
之后,我得到一个错误的结果字符串 json,如下所示:
{
"ResetableObjectThemes": {
"ThemeDark": {
"ResetablePatternObject": {},
"ResetableMaterialObject": {}
},
"ThemeLight": {
"ResetablePatternObject": {},
"ResetableMaterialObject": {}
}
}
}
但它应该是这样的:
{
"ResetableObjectThemes": {
"ThemeDark": {
"ResetablePatternObject": {
"Thickness": 3,
"BoundaryColor": {
"ColorContext": null,
"A": 255,
"R": 0,
"G": 0,
"B": 128,
},
},
"ResetableMaterialObject": {
"BoundaryThickness": 3,
"BoundaryColor": {
"ColorContext": null,
"A": 255,
"R": 0,
"G": 0,
"B": 255,
},
}
},
"ThemeLight": {
"ResetablePatternObject": {
"Thickness": 3,
"BoundaryColor": {
"ColorContext": null,
"A": 255,
"R": 0,
"G": 0,
"B": 128,
},
},
"ResetableMaterialObject": {
"BoundaryThickness": 3,
"BoundaryColor": {
"ColorContext": null,
"A": 255,
"R": 0,
"G": 0,
"B": 255,
},
}
}
}
}
这些课程是:
public class ResetableObjectTheme
{
public ResetableBaseObject ResetablePatternObject { get; set; } = new PatternObject();
public ResetableBaseObject ResetableMaterialObject { get; set; } = new MaterialObject();
}
public class PatternObject : ResetableBaseObject
{
public double Thickness { get; set; } = 1;
public Color BoundaryColor { get; set; } = Colors.Blue;
}
public class MaterialObject : ResetableBaseObject
{
public double BoundaryThickness { get; set; } = 3;
public Color BoundaryColor { get; set; } = Colors.Blue;
}
而 ResetableBaseObject 只是一个包含通用方法的基类。我已经将这种方法用于另一个东西,而不是类型 ResetableBaseObject,而是使用枚举并且序列化/反序列化工作得很好。使用字典的原因是这样我可以根据一些 UI 主题动态设置值:
ResetableObjectThemes[ThemeManager.CurrentTheme].ResetablePatternObject = new PatternObject() { Thickness = 5.5 };
为什么 System.Text.Json.JsonSerializer.Serialize/Deserialize 不能为嵌套的非枚举类型完成这项工作?
解决方案
您正在对 的属性使用多态性ResetableObjectTheme
,并且System.Text.Json
默认情况下不支持多态性。从文档:
不支持多态类型层次结构的序列化。例如,如果一个属性被定义为接口或抽象类,那么即使运行时类型具有附加属性,也只会序列化接口或抽象类上定义的属性。
本节说明了此行为的例外情况...
绕过限制的最简单方法是将 的属性声明为ResetableObjectTheme
适当的派生类型:
public class ResetableObjectTheme
{
public PatternObject ResetablePatternObject { get; set; }
public MaterialObject ResetableMaterialObject { get; set; }
}
如果您确实需要序列化和反序列化多态子类型,则需要创建一个自定义JsonConverter
,如System.Text.Json 中是否可以进行多态反序列化?.
推荐阅读
- r - 基于 geojson 多边形的限制简单特征图
- quickbooks - 操作不能使用内容类型不受支持。尝试将文件上传到 sandbox-quickbooks.api.intuit.com 时
- spring - 无法使用 Spring Boot、JUnit5 和 Kotlin 加载带有 @TestPropertySource 的 test-properties.yaml 文件
- c# - Unity ECS 不显示自包更新以来创建的实体
- sql - 如何从初始大表创建星型模式?
- plotly - 如何用plotly js制作一个垂直于x轴的平面
- c# - C# CRUD 问题 - UPDATE 面板无法按预期工作
- angular - 如何在 Angular 中同时发布多个 POST 请求?
- json - Spring Boot - 在 URI 处读取 CSV 文件并将其作为 JSON 返回
- python - 发送到多处理时我的对象是否被复制