我在将一个属性映射到 jsonb 类型时遇到这样一个问题 —— 我有一个抽象基类 BaseClass 和一个派生类 DerivedClass:- [JsonDerivedType(typeof(DerivedClass), typeDiscriminator: "derived")]
- public class BaseClass
- {
- public BaseClass() { }
- }
- public class DerivedClass : BaseClass
- {
- ....
- }
复制代码 当持久化数据后,我可能得到这样的数据:- {
- "$type": "derived",
- ...
- }<br>
复制代码 或- {
- "value": 131121,
- "$type": "derived",
- ...
- }
复制代码 第一个 json 中,类型鉴别器($type)是 json 里的第一个属性;而第二个 json 字符串则不是这种情况。当我执行 Deserialize 方法时,第二个 json 字符串会抛出异常。- System.Text.Json.JsonException : The metadata property is either not supported by the type or is not the first property in the deserialized JSON object. Path: $.$type | LineNumber: 0 | BytePositionInLine: 47.
复制代码 问题原因
System.Text.Json 的多态反序列化限制
当使用 [JsonDerivedType] 时,System.Text.Json 要求类型鉴别器(如 $type)必须是 json 中的第一个属性。如果鉴别器不在首位,反序列化会失败并抛出异常。
PostgreSQL 的存储特性
- json:以原始文本形式存储,完全保留输入的 json 字符串格式(包括空格、重复键、顺序等)。
- jsonb:以二进制形式存储,会对 json 进行解析和规范化(例如去重键、忽略多余空格、重新排序键)。
jsonb 类型会自动对 json 属性进行排序,导致存储后的属性顺序与序列化时不同。例如:{"$type":"derived","value": xxx } 存储到 jsonb 后可能变为:{"value": xxx ,"$type":"derived"} 这种顺序变化会引发 System.Text.Json 的异常。
解决方案
其实微软在官方文档中已经给出了说明:
通过设置 AllowOutOfOrderMetadataProperties 属性为 true,可解决此问题:- JsonSerializerOptions options = new() { AllowOutOfOrderMetadataProperties = true };
复制代码 如果您没有找到该属性,请升级到高版本。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |