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

如何将JSON反序列化为父类的正确派生类型?

解决Json.NET反序列化子类字段丢失的问题

嘿,我来帮你搞定这个问题!你遇到的情况很典型——当你用基类Parent去反序列化FirstChild或SecondChild的JSON时,默认情况下Json.NET只会识别基类的字段,子类的属性直接就丢失了。而且你提到没法控制序列化过程,那之前用TypeNameHandling.All的思路肯定走不通,因为这个设置需要序列化阶段就把类型标识(比如$type字段)写入JSON,而你完全没法干预那一步。

咱们换个思路:不用你手动检查JSON内容,而是让反序列化过程自动识别子类独有的字段,判断该实例化哪个类型——这个逻辑会封装在转换器里,对你来说是完全透明的。

解决方案:自定义JsonConverter

核心是写一个自定义的JsonConverter,让它在反序列化时自动检查JSON里的字段,判断应该实例化FirstChild还是SecondChild,再完成反序列化。

1. 实现自定义转换器

public class ParentConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        // 只处理Parent及其子类的转换
        return objectType == typeof(Parent);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // 先把JSON加载成JObject,方便检查字段
        var jObject = JObject.Load(reader);
        
        // 根据子类独有的字段判断类型:有firstName就是FirstChild,有lastName就是SecondChild
        if (jObject.ContainsKey("firstName"))
        {
            return jObject.ToObject<FirstChild>(serializer);
        }
        else if (jObject.ContainsKey("lastName"))
        {
            return jObject.ToObject<SecondChild>(serializer);
        }
        
        // 都不符合的话,返回基类实例
        return jObject.ToObject<Parent>(serializer);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // 序列化用默认逻辑就行,不需要自定义
        serializer.Serialize(writer, value);
    }
}

2. 使用转换器反序列化

// 创建序列化设置,添加自定义转换器
var settings = new JsonSerializerSettings();
settings.Converters.Add(new ParentConverter());

// 测试FirstChild的JSON
var firstChildJson = "{\"firstName\":\"John\",\"id\":\"1\"}";
var deserialized = JsonConvert.DeserializeObject<Parent>(firstChildJson, settings);

// 现在可以正确识别子类类型,访问子类字段
if (deserialized is FirstChild firstChild)
{
    Console.WriteLine($"First Name: {firstChild.FirstName}, ID: {firstChild.Id}");
}
// 测试SecondChild的JSON
var secondChildJson = "{\"lastName\":\"Doe\",\"id\":\"2\"}";
deserialized = JsonConvert.DeserializeObject<Parent>(secondChildJson, settings);
if (deserialized is SecondChild secondChild)
{
    Console.WriteLine($"Last Name: {secondChild.LastName}, ID: {secondChild.Id}");
}

关键说明

  • 这个方案完全不需要控制序列化过程:不管JSON是怎么生成的,只要子类有独有的字段,转换器就能自动识别。
  • 扩展性强:以后如果新增ThirdChild,只需要在ReadJson方法里加一个字段判断分支就行。
  • 大小写兼容:Json.NET默认会自动处理JSON里的小驼峰(比如firstName)和C#类里的大驼峰(比如FirstName)的映射,不用额外配置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:09:16