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

ASP.NET Core 6:处理非常规非数组JSON并转换为可用对象

问题解答

1. 遍历JSON结构

由于你使用GetFromJsonAsync<dynamic>获取的JSON在System.Text.Json中实际是JsonElement类型,可通过EnumerateObject()方法逐层遍历所有属性:

var client = new HttpClient();
// 直接获取JsonElement,比dynamic更便于结构化遍历
var jsonElement = await client.GetFromJsonAsync<JsonElement>(url);

// 遍历顶级的ID属性(如"1"、"2")
foreach (var idProperty in jsonElement.EnumerateObject())
{
    // 将字符串ID转为int类型
    int id = int.Parse(idProperty.Name);
    // 获取当前ID对应的日期集合对象
    var dateContainer = idProperty.Value;

    // 遍历每个日期属性(如"2023-03-10")
    foreach (var dateProperty in dateContainer.EnumerateObject())
    {
        DateTime date = DateTime.Parse(dateProperty.Name);
        // 获取当前日期对应的Baa数组
        var baaElements = dateProperty.Value;

        // 遍历每个Baa对象
        foreach (var baaElement in baaElements.EnumerateArray())
        {
            string label = baaElement.GetProperty("label").GetString();
            int prop1 = baaElement.GetProperty("prop1").GetInt32();
            int prop2 = baaElement.GetProperty("prop2").GetInt32();
            
            // 此处可对每个Baa对象做业务处理
        }
    }
}

2. 转换为强类型对象

原JSON本质是字符串ID为键、日期字典为值的顶级字典,日期字典又是字符串日期为键、Baa列表为值的二级字典。你可以选择两种方式转换为自定义强类型:

方式一:手动转换(简单直接)

先反序列化为字典结构,再手动映射到你的MyObject、Foo、Baa类:

// 定义强类型类
class MyObject
{
    public int Id { get; set; }
    public List<Foo> Foos { get; set; } = new List<Foo>();
}

class Foo
{
    public DateTime Date { get; set; }
    public List<Baa> Baas { get; set; } = new List<Baa>();
}

class Baa 
{
    public string Label { get; set; }
    public int Prop1 { get; set; }
    public int Prop2 { get; set; }
}

// 转换代码
var client = new HttpClient();
// 先反序列化为字典结构
var rawDict = await client.GetFromJsonAsync<Dictionary<string, Dictionary<string, List<Baa>>>>(url);

// 手动映射到强类型列表
var myObjects = rawDict.Select(kv => new MyObject
{
    Id = int.Parse(kv.Key),
    Foos = kv.Value.Select(dateKv => new Foo
    {
        Date = DateTime.Parse(dateKv.Key),
        Baas = dateKv.Value
    }).ToList()
}).ToList();

方式二:自定义JSON转换器(自动转换)

如果需要频繁转换,可编写自定义JsonConverter实现自动解析:

// 强类型类定义同上
class MyObject { /* ... */ }
class Foo { /* ... */ }
class Baa { /* ... */ }

// 自定义转换器
public class MyObjectListConverter : JsonConverter<List<MyObject>>
{
    public override List<MyObject> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var result = new List<MyObject>();

        if (reader.TokenType != JsonTokenType.StartObject)
            throw new JsonException("JSON格式错误,预期为对象");

        while (reader.Read())
        {
            if (reader.TokenType == JsonTokenType.EndObject) break;

            // 读取ID键
            string idStr = reader.GetString();
            if (!int.TryParse(idStr, out int id))
                throw new JsonException($"ID {idStr} 格式无效");

            reader.Read(); // 移动到ID对应的值
            var myObj = new MyObject { Id = id };

            // 读取日期对象
            if (reader.TokenType != JsonTokenType.StartObject)
                throw new JsonException("日期集合格式错误");

            while (reader.Read())
            {
                if (reader.TokenType == JsonTokenType.EndObject) break;

                // 读取日期字符串
                string dateStr = reader.GetString();
                if (!DateTime.TryParse(dateStr, out DateTime date))
                    throw new JsonException($"日期 {dateStr} 格式无效");

                reader.Read(); // 移动到日期对应的Baa数组
                // 反序列化Baa列表
                var baas = JsonSerializer.Deserialize<List<Baa>>(ref reader, options);
                myObj.Foos.Add(new Foo { Date = date, Baas = baas });
            }

            result.Add(myObj);
        }
        return result;
    }

    // 如果不需要序列化回JSON,可忽略Write方法
    public override void Write(Utf8JsonWriter writer, List<MyObject> value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}

// 使用转换器
var options = new JsonSerializerOptions();
options.Converters.Add(new MyObjectListConverter());

var client = new HttpClient();
var myObjects = await client.GetFromJsonAsync<List<MyObject>>(url, options);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:55:02