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

System.Text.Json序列化含Type属性对象反序列化空值问题排查

问题根因

反序列化返回null是当前实现的两处逻辑缺陷导致:

  1. 序列化输出的类型标识不标准:Write方法中使用Type.ToString()输出类型字符串,该方法的输出结果不保证和Type.FullName完全一致(特殊类型、嵌套类型会存在格式化差异),导致反序列化时拼接的程序集匹配串无法命中目标类型。
  2. 程序集未预加载:如果MyAssembly1、MyAssembly2未被当前应用程序域提前加载,Type.GetType默认不会主动加载未引用的程序集,会直接返回null。

修复方案

修改后的转换器代码如下:

internal class TypeConverter : JsonConverter<Type>
{
    // 静态构造函数预加载指定程序集,避免GetType找不到未加载的类型
    static TypeConverter()
    {
        Assembly.Load(nameof(MyAssembly1));
        Assembly.Load(nameof(MyAssembly2));
    }

    public override Type Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        string typeFullName = reader.GetString();
        if (string.IsNullOrWhiteSpace(typeFullName))
            return null;
        
        // 按优先级匹配两个程序集中的类型
        return Type.GetType($"{typeFullName}, {nameof(MyAssembly1)}", throwOnError: false)
            ?? Type.GetType($"{typeFullName}, {nameof(MyAssembly2)}", throwOnError: false);
    }

    public override void Write(Utf8JsonWriter writer, Type value, JsonSerializerOptions options)
    {
        // 输出标准的类型全限定名,保证反序列化匹配准确
        writer.WriteStringValue(value.FullName);
    }
}

如果修改后仍然返回null,可以临时将throwOnError设为true,查看具体异常信息排查匹配失败原因,常见原因包括类名拼写错误、命名空间变更、程序集版本不匹配等。

方案可行性与推荐建议

  • 可控场景下可行:如果你完全掌握序列化、反序列化的两端环境,且JSON数据源完全可信,该方案可以正常使用,你已经限制了仅能加载指定的两个自定义程序集,大幅降低了类型注入的安全风险。
  • 非可信场景绝对不推荐:如果JSON输入来自外部不可信来源,哪怕限制了程序集范围,仍有可能被利用构造恶意类型执行危险操作。
  • 额外注意事项:需要保证序列化、反序列化两端的MyAssembly1、MyAssembly2版本一致,类名、命名空间变更会导致历史序列化数据无法反序列化。

内容的提问来源于stack exchange,提问作者monadoboy007

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 02:24:03