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

C# .NET 6中如何将JSON对象反序列化为自定义数组模型

解答

没有仅靠内置序列化特性、完全不写自定义代码就能实现该需求的方案:接口返回的Columns是键为动态数字的对象结构,和目标数组属于完全不同的JSON结构类型,内置的属性映射、类型转换特性只能处理静态结构的匹配,无法自动展开动态键为数组元素。
但你只需要写极少量的轻量转换逻辑,复用JSON库自带的序列化能力,不需要手动逐节点解析JSON,两种常用库的实现方式如下:

首先定义你需要的目标模型:

// 根响应模型
public class ApiResponse
{
    // 后续给这个属性挂载转换器即可
    public List<Column> Columns { get; set; }
}

// 你期望的列结构
public class Column
{
    public string Number { get; set; }
    public List<string> Fuels { get; set; }
}

方案1:使用Newtonsoft.Json

实现一个针对List<Column>的自定义转换器,核心逻辑是先把动态键对象反序列化为字典,再做一次结构映射:

using Newtonsoft.Json;

public class ColumnListConverter : JsonConverter<List<Column>>
{
    // 内部临时类,匹配接口返回的单条列结构
    private class ColumnRaw
    {
        public List<string> Fuels { get; set; }
    }

    public override List<Column> ReadJson(JsonReader reader, Type objectType, List<Column> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 复用内置能力直接把动态对象转成字典
        var rawDict = serializer.Deserialize<Dictionary<string, ColumnRaw>>(reader);
        // 映射为目标结构
        return rawDict?.Select(kv => new Column
        {
            Number = kv.Key,
            Fuels = kv.Value.Fuels
        }).ToList();
    }

    public override void WriteJson(JsonWriter writer, List<Column> value, JsonSerializer serializer)
    {
        // 不需要序列化回原结构可以直接留空抛异常,需要的话反向转字典序列化即可
        throw new NotImplementedException();
    }
}

给属性加特性即可生效:

public class ApiResponse
{
    [JsonConverter(typeof(ColumnListConverter))]
    public List<Column> Columns { get; set; }
}

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

逻辑和Newtonsoft版本一致,仅转换器基类和API有区别:

using System.Text.Json;
using System.Text.Json.Serialization;

public class ColumnListConverter : JsonConverter<List<Column>>
{
    private class ColumnRaw
    {
        public List<string> Fuels { get; set; }
    }

    public override List<Column> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var rawDict = JsonSerializer.Deserialize<Dictionary<string, ColumnRaw>>(ref reader, options);
        return rawDict?.Select(kv => new Column
        {
            Number = kv.Key,
            Fuels = kv.Value.Fuels
        }).ToList();
    }

    public override void Write(Utf8JsonWriter writer, List<Column> value, JsonSerializerOptions options)
    {
        throw new NotImplementedException();
    }
}

挂载特性的方式:

public class ApiResponse
{
    [JsonConverter(typeof(ColumnListConverter))]
    public List<Column> Columns { get; set; }
}

这种实现方式没有冗余代码,所有JSON解析逻辑都由库本身完成,你只需要做最后一步结构映射,后续如果接口给Columns新增了字段,只需要同步修改内部的ColumnRaw类和映射逻辑即可,比自动生成一堆_1/_2的冗余类维护成本低很多。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 12:25:17