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

为何为基类添加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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 11:01:15