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

如何遍历Gate.io API返回JObject中的币种键与对应值?

如何规范遍历Gate.io API返回的JObject中的币种键值对?

问题背景

我从Gate.io交易接口拿到了包含账户余额的JSON数据,想要遍历available字段下的各币种名称和对应的可用余额。原始JSON数据如下:

{ 
  "result": "true", 
  "available": { 
    "BTC": "0.83337671", 
    "LTC": "94.364", 
    "ETH": "0.07161", 
    "ETC": "82.35029899" 
  }, 
  "locked": { 
    "BTC": "0.0002", 
    "YAC": "10.01" 
  } 
}

我尝试用Newtonsoft.Json的JObject解析,但遍历的时候遇到了问题:

var coinData = JObject.Parse(@"{ ""result"": ""true"", ""available"": { ""BTC"": ""0.83337671"", ""LTC"": ""94.364"", ""ETH"": ""0.07161"", ""ETC"": ""82.35029899"" }, ""locked"": { ""BTC"": ""0.0002"", ""YAC"": ""10.01"" } }")["available"]; 
foreach (JToken item in coinData) { 
    // 这里发现JToken没法直接访问Key属性,不知道怎么正确解析
}

后来我临时用字符串分割的方法解决了,但总觉得不够规范:

foreach (JToken item in coinData) { 
    var data = item.ToString().Replace("\"", String.Empty).Split(':'); 
    // data[0]是币种名称,data[1]是余额
}

想请教有没有更规范的实现方式?


规范的解决方法

其实你遇到的问题核心是没搞清楚JToken的实际类型——available是一个JSON对象,里面的每个子项都是JProperty类型(而不是普通的JToken)。下面给你几种更健壮、更符合.NET编码规范的方法:

方法1:直接遍历JProperty(最直接)

你可以明确指定遍历的是JProperty类型,这样就能直接获取到键(币种名)和值(余额):

// 假设jsonString是你从API拿到的原始JSON字符串
var jObject = JObject.Parse(jsonString);
var availableBalances = jObject["available"];

foreach (JProperty prop in availableBalances.Children<JProperty>())
{
    string coinSymbol = prop.Name; // 比如BTC、LTC
    string balanceStr = prop.Value.ToString(); // 余额字符串
    
    // 如果需要数值类型,建议用decimal(避免浮点精度问题)
    if (decimal.TryParse(balanceStr, out decimal balance))
    {
        // 在这里处理数值类型的余额,比如存入数据库或展示
        Console.WriteLine($"币种:{coinSymbol},可用余额:{balance}");
    }
}

方法2:转为Dictionary类型(更灵活)

如果你习惯用字典的方式操作,可以直接把available字段转成Dictionary<string, string>或者Dictionary<string, decimal>:

var jObject = JObject.Parse(jsonString);

// 转成字符串字典
var availableStrDict = jObject["available"].ToObject<Dictionary<string, string>>();
foreach (var kvp in availableStrDict)
{
    Console.WriteLine($"币种:{kvp.Key},余额:{kvp.Value}");
}

// 直接转成decimal字典(更省心,适合需要数值计算的场景)
var availableDecimalDict = jObject["available"].ToObject<Dictionary<string, decimal>>();
foreach (var kvp in availableDecimalDict)
{
    Console.WriteLine($"币种:{kvp.Key},余额:{kvp.Value:N8}"); // 格式化显示8位小数
}

方法3:定义实体类序列化(推荐长期项目)

如果你的项目经常需要处理这类余额数据,建议定义对应的实体类,这样代码可读性和可维护性会高很多:

// 定义实体类,JsonProperty属性对应JSON字段名
public class WalletBalanceResponse
{
    [JsonProperty("result")]
    public string Result { get; set; }
    
    [JsonProperty("available")]
    public Dictionary<string, decimal> AvailableBalances { get; set; }
    
    [JsonProperty("locked")]
    public Dictionary<string, decimal> LockedBalances { get; set; }
}

// 解析时直接转成实体类
var response = JsonConvert.DeserializeObject<WalletBalanceResponse>(jsonString);

// 遍历可用余额
foreach (var kvp in response.AvailableBalances)
{
    Console.WriteLine($"币种:{kvp.Key},可用余额:{kvp.Value}");
}

// 遍历锁定余额也一样
foreach (var kvp in response.LockedBalances)
{
    Console.WriteLine($"币种:{kvp.Key},锁定余额:{kvp.Value}");
}

为什么不推荐字符串分割的方法?

你之前的字符串分割方法虽然能临时解决问题,但存在很多隐患:

  • 如果JSON格式发生变化(比如余额值里包含冒号或引号),代码会直接失效;
  • 需要自己处理字符串转数值的逻辑,容易出现格式错误;
  • 代码可读性差,其他开发者接手时需要花时间理解你的自定义逻辑。

上面的几种方法都是基于Newtonsoft.Json的原生API,能更好地处理JSON的各种边界情况,也更符合.NET的编码规范。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:26:00