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

如何用Newtonsoft.Json反序列化含不同类型元素的JSON数组

这个多态反序列化的问题我之前做过滤逻辑的时候经常碰到,Newtonsoft.Json其实有很成熟的解决办法,咱们一步步来搞定它:

解决方案核心思路

利用基类+派生类的结构兼容group和condition两种类型,再配合自定义JsonConverter,根据JSON里的type字段自动判断要反序列化的目标类。

1. 补全类结构定义

先创建一个抽象基类,让Group和Condition都继承它,这样就能统一放在conditions数组里:

// 抽象基类,统一两种过滤类型
public abstract class FilterBase
{
    [JsonProperty("type")]
    public abstract string Type { get; }
}

// Condition类型的具体实现
public class Condition : FilterBase
{
    public override string Type => "condition";
    
    [JsonProperty("metric")]
    public string Metric { get; set; }
    
    [JsonProperty("operator")]
    public string Operator { get; set; }
    
    [JsonProperty("value")]
    public string Value { get; set; }
}

// 补全你未写完的Group类
public class Group : FilterBase
{
    public override string Type => "group";
    
    [JsonProperty("logicalOperator")]
    public string LogicalOperator { get; set; }
    
    [JsonProperty("conditions")]
    public List<FilterBase> Conditions { get; set; }
}

2. 实现自定义JsonConverter

这个转换器的作用是读取JSON里的type字段,决定把当前节点反序列化成Group还是Condition:

public class FilterConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        // 只处理FilterBase及其派生类
        return typeof(FilterBase).IsAssignableFrom(objectType);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        var jObject = JObject.Load(reader);
        var filterType = jObject["type"].Value<string>();
        
        // 根据type字段匹配对应的类
        switch (filterType)
        {
            case "group":
                return jObject.ToObject<Group>(serializer);
            case "condition":
                return jObject.ToObject<Condition>(serializer);
            default:
                throw new JsonSerializationException($"未知的过滤类型: {filterType}");
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // 序列化时直接用默认逻辑即可
        serializer.Serialize(writer, value);
    }
}

3. 执行反序列化操作

最后只需要在反序列化时指定咱们写的转换器,就能完美处理混合类型的数组了:

// 你的原始JSON字符串
var json = @"{ ""type"": ""group"", ""logicalOperator"": ""or"", ""conditions"":[{ ""type"": ""condition"", ""metric"": ""CTR"", ""operator"": ""&gt;="", ""value"": ""123"" }, { ""type"": ""group"", ""logicalOperator"": ""and"", ""conditions"": [{ ""type"": ""condition"", ""metric"": ""CTR"", ""operator"": ""&gt;="", ""value"": ""123"" }] } ] }";

// 配置序列化设置,添加自定义转换器
var settings = new JsonSerializerSettings
{
    Converters = new List<JsonConverter> { new FilterConverter() }
};

// 反序列化为Group类型(因为你的根节点是group)
var filterGroup = JsonConvert.DeserializeObject<Group>(json, settings);

后续如果需要新增其他过滤类型,只需要新增一个继承FilterBase的类,再在转换器的switch里加个case就行,扩展性很强。


内容的提问来源于stack exchange,提问作者Максим Устелемов

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 03:45:05