为何为基类添加TypeDescriptor.AddAttributes对System.Text.Json序列化无效?
System.Text.Json动态添加JsonDerivedType无效的原因
核心原因是:System.Text.Json的多态序列化逻辑不读取TypeDescriptor中添加的属性,它只识别编译时标注的[JsonDerivedType],或者通过自身配置API设置的多态规则。
具体细节:
- 编译时在Base类上标注
[JsonDerivedType(typeof(Derived))]时,这个属性会被System.Text.Json的元数据读取器在程序集加载阶段识别,序列化器会提前知道Base类型需要处理Derived的多态序列化,因此序列化时会解析实例的真实类型并序列化所有属性。 TypeDescriptor.AddAttributes()是.NET组件模型(用于控件属性绑定、数据验证等场景)的API,System.Text.Json的序列化引擎完全不依赖这个系统来获取JSON序列化配置,所以你动态添加的JsonDerivedTypeAttribute对序列化器来说等于不存在。- 当序列化器没有获取到Base的多态配置时,它会严格按照变量的静态类型(Base)来序列化,只会处理Base中定义的属性,忽略派生类Derived的额外属性。
正确的动态配置方式
如果需要动态添加多态序列化规则,应该用System.Text.Json自带的配置API,比如通过JsonSerializerOptions和DefaultJsonTypeInfoResolver来设置:
using System.Text.Json; using System.Text.Json.Serialization.Metadata; // 配置序列化选项 var options = new JsonSerializerOptions(); var typeInfoResolver = options.TypeInfoResolver as DefaultJsonTypeInfoResolver; // 添加类型元数据修改器 typeInfoResolver.Modifiers.Add(typeInfo => { if (typeInfo.Type == typeof(Base)) { typeInfo.PolymorphismOptions = new JsonPolymorphismOptions { DerivedTypes = { new JsonDerivedType(typeof(Derived)) } }; } }); // 测试序列化 var d = new Derived() { F1 = "111", F2 = "222" }; Base b = d; var s = JsonSerializer.Serialize(b, options); Console.WriteLine(s); // 输出包含F1和F2的JSON
这样就能实现动态配置多态序列化,让序列化器识别Derived类型并序列化所有属性。
内容的提问来源于stack exchange,提问作者sergeyxzc
相关产品推荐
相关产品推荐

