.NET C#中如何反序列化含超大整数的JSON对象
解决C#反序列化火币API超大整数字段问题
问题核心:火币API返回的交易数据中,最内层id字段值是远超ulong.MaxValue的超大整数,直接用数值类型反序列化会抛出溢出异常,且C#无内置BigNumber类型,需通过以下方案处理:
一、使用System.Text.Json的处理方式
方案1:将超大整数字段定义为string类型
若无需对该id做数值计算,直接存为字符串是最简单的方案,模型定义如下:
using System.Collections.Generic; using System.Text.Json.Serialization; public class HuobiTradeResponse { public string ch { get; set; } public string status { get; set; } public long ts { get; set; } public List<TradeGroup> data { get; set; } } public class TradeGroup { public long id { get; set; } public long ts { get; set; } public List<TradeDetail> data { get; set; } } public class TradeDetail { public string id { get; set; } // 超大整数字段改为string public long ts { get; set; } [JsonPropertyName("trade-id")] public long TradeId { get; set; } public decimal amount { get; set; } public decimal price { get; set; } public string direction { get; set; } }
反序列化代码:
var json = await new HttpClient().GetStringAsync("https://api.huobi.pro/market/history/trade?symbol=btcusdt"); var response = JsonSerializer.Deserialize<HuobiTradeResponse>(json);
方案2:自定义转换器转为BigInteger
若需要对该id做数值运算,可使用System.Numerics.BigInteger类型,并自定义转换器处理:
首先添加System.Numerics引用,然后实现转换器:
using System.Numerics; using System.Text.Json; using System.Text.Json.Serialization; public class BigIntegerConverter : JsonConverter<BigInteger> { public override BigInteger Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { if (reader.TokenType == JsonTokenType.Number) { try { return reader.GetInt64(); } catch { // 超出Int64范围时,读取原始数值字符串解析 return BigInteger.Parse(reader.ValueSpan); } } else if (reader.TokenType == JsonTokenType.String) { return BigInteger.Parse(reader.GetString()); } throw new JsonException("无法将JSON值转换为BigInteger"); } public override void Write(Utf8JsonWriter writer, BigInteger value, JsonSerializerOptions options) { writer.WriteNumberValue(value); } }
修改模型字段并指定转换器:
public class TradeDetail { [JsonConverter(typeof(BigIntegerConverter))] public BigInteger id { get; set; } // 其他字段同方案1 }
反序列化时传入转换器配置:
var options = new JsonSerializerOptions(); options.Converters.Add(new BigIntegerConverter()); var response = JsonSerializer.Deserialize<HuobiTradeResponse>(json, options);
二、使用Newtonsoft.Json的处理方式
方案1:定义为string类型
模型定义(注意使用Newtonsoft的JsonProperty特性):
using System.Collections.Generic; using Newtonsoft.Json; public class HuobiTradeResponse { public string ch { get; set; } public string status { get; set; } public long ts { get; set; } public List<TradeGroup> data { get; set; } } public class TradeGroup { public long id { get; set; } public long ts { get; set; } public List<TradeDetail> data { get; set; } } public class TradeDetail { public string id { get; set; } public long ts { get; set; } [JsonProperty("trade-id")] public long TradeId { get; set; } public decimal amount { get; set; } public decimal price { get; set; } public string direction { get; set; } }
反序列化代码:
var response = JsonConvert.DeserializeObject<HuobiTradeResponse>(json);
方案2:直接使用BigInteger
Newtonsoft.Json原生支持BigInteger类型,无需自定义转换器,直接修改模型字段即可:
using System.Numerics; public class TradeDetail { public BigInteger id { get; set; } // 其他字段同方案1 }
反序列化代码:
var response = JsonConvert.DeserializeObject<HuobiTradeResponse>(json);
补充说明
你之前尝试的BigNumber并非C#内置类型,因此无法生效。推荐优先使用string方案(无需数值运算时),需运算则选择BigInteger方案。
内容的提问来源于stack exchange,提问作者smgtkn
相关产品推荐
相关产品推荐

