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

C#如何反序列化嵌套层数不固定的JSON数组

from Postman

实现方案

固定层级的实体类无法适配嵌套层数不固定的JSON结构,通过自定义JSON转换器递归遍历所有嵌套的data字段,即可直接提取到最内层的HistoryData对象集合,无需逐层定义嵌套实体类。


方案1:使用Newtonsoft.Json(Json.NET)实现

  1. 简化实体类定义,给最外层data字段添加转换器注解:
public class BrowsingDataObject
{
    public string api_msg { get; set; }
    public string api_code { get; set; }
    public string api_status { get; set; }
    // 直接指定最终解析目标类型,由转换器处理嵌套结构
    [Newtonsoft.Json.JsonConverter(typeof(NestedDataArrayConverter<HistoryData>))]
    public HistoryData[] data { get; set; }
}

public class HistoryData
{
    public string date_time { get; set; }
    public string url { get; set; }
    public string browser_source { get; set; }
}
  1. 实现自定义递归转换器:
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;

public class NestedDataArrayConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType) => objectType == typeof(T[]);

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken token = JToken.Load(reader);
        return ExtractInnerData(token).ToArray();
    }

    private IEnumerable<T> ExtractInnerData(JToken token)
    {
        // 遍历数组元素
        if (token.Type == JTokenType.Array)
        {
            foreach (var item in token.Children())
            {
                foreach (var data in ExtractInnerData(item))
                    yield return data;
            }
        }
        // 处理对象,检查是否还有嵌套的data字段
        else if (token.Type == JTokenType.Object)
        {
            var dataProp = token["data"];
            if (dataProp != null)
            {
                foreach (var data in ExtractInnerData(dataProp))
                    yield return data;
            }
            else
            {
                // 无嵌套data,直接反序列化为目标对象
                yield return token.ToObject<T>();
            }
        }
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
        => throw new NotImplementedException("仅用于反序列化,序列化功能未实现");
}
  1. 直接调用反序列化即可,适配任意嵌套层数:
var result = JsonConvert.DeserializeObject<BrowsingDataObject>(jsonResponse);

方案2:使用.NET内置System.Text.Json实现

  1. 实体类注解:
public class BrowsingDataObject
{
    public string api_msg { get; set; }
    public string api_code { get; set; }
    public string api_status { get; set; }
    [System.Text.Json.Serialization.JsonConverter(typeof(NestedDataArrayConverter<HistoryData>))]
    public HistoryData[] data { get; set; }
}

public class HistoryData
{
    public string date_time { get; set; }
    public string url { get; set; }
    public string browser_source { get; set; }
}
  1. 自定义转换器实现:
using System.Text.Json;
using System.Text.Json.Serialization;

public class NestedDataArrayConverter<T> : JsonConverter<T[]>
{
    public override T[]? Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        using JsonDocument doc = JsonDocument.ParseValue(ref reader);
        return ExtractInnerData(doc.RootElement, options).ToArray();
    }

    private IEnumerable<T> ExtractInnerData(JsonElement element, JsonSerializerOptions options)
    {
        if (element.ValueKind == JsonValueKind.Array)
        {
            foreach (var item in element.EnumerateArray())
            {
                foreach (var data in ExtractInnerData(item, options))
                    yield return data;
            }
        }
        else if (element.ValueKind == JsonValueKind.Object)
        {
            if (element.TryGetProperty("data", out var dataProp))
            {
                foreach (var data in ExtractInnerData(dataProp, options))
                    yield return data;
            }
            else
            {
                yield return element.Deserialize<T>(options)!;
            }
        }
    }

    public override void Write(Utf8JsonWriter writer, T[] value, JsonSerializerOptions options)
        => throw new NotImplementedException("仅用于反序列化,序列化功能未实现");
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 14:45:05