从CoinGecko API反序列化JSON数据时遇到问题
解决方案:处理CoinGecko动态键JSON反序列化
你的问题核心是类结构和返回的JSON格式完全不匹配:返回的顶级JSON是一个以币种名称为键的对象,每个币种下又是以货币类型为键的价格对象,而你定义的SimplePrice和Coin类完全对应不上这种动态键结构,所以反序列化后得到空实例。
下面是两种可行的解决方法:
方法1:使用嵌套字典直接反序列化
这是最简单的方式,直接用Dictionary<string, Dictionary<string, decimal>>来匹配JSON结构(用decimal存储价格比float更精准,避免浮点误差):
使用Newtonsoft.Json的示例
using Newtonsoft.Json; using System.Net.Http; using System.Threading.Tasks; public async Task GetCoinPrices() { using var httpClient = new HttpClient(); var url = "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin%2Cethereum&vs_currencies=usd%2Ceur&include_market_cap=false&include_24hr_vol=false&include_24hr_change=false&include_last_updated_at=false&precision=1"; var jsonString = await httpClient.GetStringAsync(url); var priceData = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, decimal>>>(jsonString); // 访问数据示例 if (priceData.TryGetValue("bitcoin", out var bitcoinPrices)) { if (bitcoinPrices.TryGetValue("usd", out var bitcoinUsdPrice)) { // 使用bitcoinUsdPrice } } }
使用System.Text.Json的示例
using System.Net.Http; using System.Text.Json; using System.Threading.Tasks; public async Task GetCoinPrices() { using var httpClient = new HttpClient(); var url = "https://api.coingecko.com/api/v3/simple/price?ids=bitcoin%2Cethereum&vs_currencies=usd%2Ceur&include_market_cap=false&include_24hr_vol=false&include_24hr_change=false&include_last_updated_at=false&precision=1"; var responseStream = await httpClient.GetStreamAsync(url); var priceData = await JsonSerializer.DeserializeAsync<Dictionary<string, Dictionary<string, decimal>>>(responseStream); // 访问数据示例 if (priceData != null && priceData.ContainsKey("ethereum")) { var ethereumEurPrice = priceData["ethereum"]["eur"]; // 使用价格 } }
方法2:自定义类结合字典(更面向对象)
如果想封装成类,可以把每个币种的价格集合定义为字典,顶级用字典映射币种名称到价格对象:
public class CoinPriceData { // 键是货币类型(usd/eur等),值是对应价格 public Dictionary<string, decimal> Prices { get; set; } = new Dictionary<string, decimal>(); } // 反序列化时使用Dictionary<string, CoinPriceData> var priceData = JsonConvert.DeserializeObject<Dictionary<string, CoinPriceData>>(jsonString); // 访问示例 var bitcoinEurPrice = priceData["bitcoin"].Prices["eur"];
为什么你的原类不行?
你定义的SimplePrice只有一个Coin属性,但JSON顶级是多个币种键(bitcoin、ethereum),根本没有名为Coin的字段;而Coin类的Price属性也对应不上JSON里的usd/eur动态键,所以反序列化器找不到匹配的字段,最终得到空实例。
内容的提问来源于stack exchange,提问作者Robert Altman
相关产品推荐
相关产品推荐

