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

调用Ethplorer.io API后,如何将TokenInfo的Price转为C#字典?

解决Ethplorer API Price字段反序列化的类型兼容问题

这种同一个字段同时返回布尔值(无价格)和对象(有价格)的API设计确实有点棘手,不过咱们有几种靠谱的解决方案,按类型安全程度给你列出来:

方案1:自定义JsonConverter(最推荐,类型安全)

这个方法能让反序列化过程自动处理两种情况,把Price转换成强类型对象或者字典,完全不用手动判断。

步骤1:定义Price的强类型类(可选,比字典更安全)

如果你知道Price字段的具体结构,先定义一个对应类:

public class PriceData
{
    public double? Rate { get; set; }
    public string Currency { get; set; }
    public double? Diff { get; set; }
    // 其他API返回的价格字段都可以加上
}

步骤2:编写自定义转换器

这个转换器会在反序列化时判断JSON token类型,自动处理布尔值和对象的情况:

public class PriceConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        // 这里指定要转换的目标类型,比如PriceData或者Dictionary<string, object>
        return objectType == typeof(PriceData);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // 如果是布尔值且为false,直接返回null表示无价格
        if (reader.TokenType == JsonToken.Boolean && (bool)reader.Value == false)
        {
            return null;
        }
        // 如果是对象,正常反序列化为目标类型
        return serializer.Deserialize(reader, objectType);
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        // 序列化时如果Price为null,就输出false,否则输出对象
        if (value == null)
        {
            writer.WriteValue(false);
        }
        else
        {
            serializer.Serialize(writer, value);
        }
    }
}

步骤3:修改TokenInfo类的Price属性

给Price属性加上转换器特性,指定用咱们写的转换器:

public class TokenInfo
{
    // 其他自动生成的属性...
    [JsonConverter(typeof(PriceConverter))]
    public PriceData Price { get; set; }
    // 要是想用字典的话,改成下面这样:
    // [JsonConverter(typeof(PriceConverter))]
    // public Dictionary<string, object> Price { get; set; }
}

之后再用JsonConvert.DeserializeObject<TokenInfo>(rawJSON)反序列化,Price字段会自动处理:无价格时为null,有价格时就是完整的PriceData对象/字典。

方案2:用JObject临时转换(快速灵活,无需修改类)

如果不想写转换器,也可以利用Newtonsoft.Json的JObject来处理自动生成的object类型Price:

var tokenInfo = JsonConvert.DeserializeObject<TokenInfo>(rawJSON);

if (tokenInfo.Price is bool)
{
    // 无价格逻辑
    Console.WriteLine("该代币暂无价格信息");
}
else
{
    // 把object转成JObject,再提取数据
    var priceJObj = (JObject)tokenInfo.Price;
    var rate = priceJObj["rate"].Value<double>();
    var currency = priceJObj["currency"].Value<string>();
    
    // 或者直接转成PriceData类
    var priceData = priceJObj.ToObject<PriceData>();
}

方案3:dynamic类型快速验证(适合临时测试)

如果只是快速验证API数据,不想改类也不想写转换器,可以用dynamic:

var rawResult = JsonConvert.DeserializeObject<dynamic>(rawJSON);

foreach (var token in rawResult.tokens)
{
    if (token.Price is bool && (bool)token.Price == false)
    {
        Console.WriteLine("无价格");
    }
    else
    {
        // 转成字典或强类型
        var priceDict = JsonConvert.DeserializeObject<Dictionary<string, object>>(token.Price.ToString());
        Console.WriteLine($"当前价格:{priceDict["rate"]} {priceDict["currency"]}");
    }
}

缺点是没有编译时类型检查,容易写错字段名,适合临时场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:46:20