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

如何用Newtonsoft.Json反序列化带键嵌套JObject为实体列表

解决方案:将动态键的JSON反序列化为带Name字段的列表

这里有两种实用方案,帮你用Newtonsoft.Json实现需求——把JSON中作为键的币种名称自动存入实体的Name字段,同时转换成列表类型:

方案一:手动转换字典到列表(简单直接)

首先,我们需要调整你的响应类,把Coins定义为Dictionary<string, WhatToMineCalculatorResponse>,因为JSON里的coins本质是一个键值对集合:

internal class WhatToMineCalculatorsResponse
{
    [JsonProperty("coins")]
    public Dictionary<string, WhatToMineCalculatorResponse> Coins { get; set; }
}

internal class WhatToMineCalculatorResponse
{
    // 用于存储币种名称的字段
    public string Name { get; set; }
    
    [JsonProperty("id")]
    public int Id { get; set; }
    
    [JsonProperty("tag")]
    public string Symbol { get; set; }
    
    [JsonProperty("status")]
    public string Status { get; set; }
    
    [JsonProperty("algorithm")]
    public string Algo { get; set; }
    
    [JsonProperty("listed")]
    public bool IsListed { get; set; }
    
    // 记得补充JSON里的其他字段,比如lagging、testing等
    [JsonProperty("lagging")]
    public bool IsLagging { get; set; }
    
    [JsonProperty("testing")]
    public bool IsTesting { get; set; }
}

反序列化后,只需要遍历字典,把键赋值给每个实体的Name,再转成列表即可:

// 假设你已经获取到API返回的JSON字符串
string jsonContent = /* 从接口获取的JSON */;

// 反序列化为带字典的响应对象
var rawResponse = JsonConvert.DeserializeObject<WhatToMineCalculatorsResponse>(jsonContent);

// 转换为带Name字段的列表
var coinList = rawResponse.Coins.Select(kv => 
{
    kv.Value.Name = kv.Key;
    return kv.Value;
}).ToList();

这种方法的优势是代码少、易理解,适合快速实现需求。

方案二:自定义JsonConverter(优雅自动化)

如果希望反序列化过程更自动化,不用每次手动转换字典,可以自定义一个JsonConverter,让Newtonsoft.Json自动帮你完成键到Name字段的赋值:

第一步:创建自定义转换器

public class CoinListConverter : JsonConverter<IList<WhatToMineCalculatorResponse>>
{
    public override IList<WhatToMineCalculatorResponse> ReadJson(JsonReader reader, Type objectType, IList<WhatToMineCalculatorResponse> existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 先把JSON对象反序列化为字典
        var coinDictionary = serializer.Deserialize<Dictionary<string, WhatToMineCalculatorResponse>>(reader);
        
        // 将字典键赋值给实体Name,再转成列表
        return coinDictionary.Select(kv => 
        {
            kv.Value.Name = kv.Key;
            return kv.Value;
        }).ToList();
    }

    public override void WriteJson(JsonWriter writer, IList<WhatToMineCalculatorResponse> value, JsonSerializer serializer)
    {
        // 如果需要把列表序列回JSON对象,这里可以把列表转回字典
        var coinDictionary = value.ToDictionary(coin => coin.Name, coin => coin);
        serializer.Serialize(writer, coinDictionary);
    }
}

第二步:给响应类的Coins属性添加转换器特性

internal class WhatToMineCalculatorsResponse
{
    [JsonProperty("coins")]
    // 指定使用我们自定义的转换器
    [JsonConverter(typeof(CoinListConverter))]
    public IList<WhatToMineCalculatorResponse> Coins { get; set; }
}

// 实体类和方案一一致,记得补充所有需要的字段
internal class WhatToMineCalculatorResponse
{
    public string Name { get; set; }
    
    [JsonProperty("id")]
    public int Id { get; set; }
    
    [JsonProperty("tag")]
    public string Symbol { get; set; }
    
    [JsonProperty("status")]
    public string Status { get; set; }
    
    [JsonProperty("algorithm")]
    public string Algo { get; set; }
    
    [JsonProperty("listed")]
    public bool IsListed { get; set; }
    
    [JsonProperty("lagging")]
    public bool IsLagging { get; set; }
    
    [JsonProperty("testing")]
    public bool IsTesting { get; set; }
}

第三步:直接反序列化即可

string jsonContent = /* 从接口获取的JSON */;
var response = JsonConvert.DeserializeObject<WhatToMineCalculatorsResponse>(jsonContent);

// 此时response.Coins已经是每个Item都包含Name字段的列表了
foreach (var coin in response.Coins)
{
    Console.WriteLine($"币种名称:{coin.Name},符号:{coin.Symbol}");
}

这种方案的优势是一次定义,后续反序列化代码非常简洁,适合需要多次处理这类JSON的场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:46:14