在Xamarin Forms中使用CryptoCompare API遇JSON反序列化问题求助
解决CryptoCompare API反序列化JSON对象为List的问题
嘿,我来帮你搞定这个反序列化的坑!咱们先理清楚问题根源:
你调用API拿到的返回是单个JSON对象(比如{"NZD":3.89,"BTC":0.0001567}),但你的代码试图把它反序列化成List<Coin>——而列表类型要求的是JSON数组(用[]包裹的结构,比如[{"Currency":"USD",...}, {...}]),这俩结构完全不匹配,所以Newtonsoft.Json才会报错,Coins变量自然就成null了。
接下来给你两种实用的解决思路,你可以根据自己的需求选择:
思路1:用Dictionary灵活处理动态货币类型
如果以后你可能会请求不同的目标货币(比如随时加EUR、GBP之类的),这种方式最灵活:
1. 保持你的Coin模型不变(如果需要的话)
你的Coin模型可以保留,我们只需要修改反序列化的逻辑:
2. 修改DataService中的GetCoinsAsync方法
public async Task<List<Coin>> GetCoinsAsync() { var response = await client.GetAsync("https://min-api.cryptocompare.com/data/price?fsym=XRP&tsyms=USD,BTC"); var content = await response.Content.ReadAsStringAsync(); // 先把JSON对象反序列化为字典:键是货币代码,值是对应价格 var priceDictionary = JsonConvert.DeserializeObject<Dictionary<string, float>>(content); // 把字典转换成你需要的List<Coin> var coins = priceDictionary.Select(kv => new Coin { Currency = kv.Key, Price = kv.Value, // 这里处理USD字段:如果当前货币是USD,直接用价格;否则取字典里的USD价格(确保请求的tsyms包含USD) USD = priceDictionary.TryGetValue("USD", out var usdPrice) ? usdPrice.ToString() : null }).ToList(); return coins; }
思路2:用强类型类匹配固定的API返回结构
如果你的请求目标货币是固定的(比如永远只查USD和BTC),可以定义一个和API返回结构完全匹配的类,这样代码更直观:
1. 新增一个PriceResponse类
public class PriceResponse { public float USD { get; set; } public float BTC { get; set; } }
2. 修改GetCoinsAsync方法
public async Task<List<Coin>> GetCoinsAsync() { var response = await client.GetAsync("https://min-api.cryptocompare.com/data/price?fsym=XRP&tsyms=USD,BTC"); var content = await response.Content.ReadAsStringAsync(); // 反序列化为强类型的PriceResponse var priceData = JsonConvert.DeserializeObject<PriceResponse>(content); // 转换成List<Coin> var coins = new List<Coin> { new Coin { Currency = "USD", Price = priceData.USD, USD = priceData.USD.ToString() }, new Coin { Currency = "BTC", Price = priceData.BTC, USD = priceData.USD.ToString() } }; return coins; }
额外小建议
看你的Coin模型里有个USD字段,如果你是想存储每个加密货币对应的USD价格,那在思路1里的处理方式就ok;如果这个字段是冗余的(比如Price已经是对应货币的价格),可以考虑移除它,让模型更简洁。
内容的提问来源于stack exchange,提问作者stackman
相关产品推荐
相关产品推荐

