如何用System.Text.Json处理超出ulong范围的BigInteger序列化与反序列化?
处理System.Text.Json中超范围数值与BigInteger的序列化/反序列化方案
针对第三方API返回超大数值、需要用BigInteger处理,且System.Text.Json默认不支持数值与BigInteger直接互转的问题,以下是几个可行方案:
方案一:自定义BigInteger转换器(推荐)
写一个自定义的JsonConverter<BigInteger>,同时处理**数值转BigInteger(反序列化)和BigInteger转数值(序列化)**的逻辑,完全适配场景:
public class BigIntegerConverter : JsonConverter<BigInteger> { public override BigInteger Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { // 兼容JSON数值和字符串两种格式 if (reader.TokenType == JsonTokenType.Number) { // .NET 6+可直接调用TryGetBigInteger,低版本则转字符串解析 if (reader.TryGetBigInteger(out var bigInt)) return bigInt; return BigInteger.Parse(reader.GetString()); } 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) { // 序列化时输出JSON数值而非字符串 writer.WriteRawValue(value.ToString()); } }
使用时只需在序列化/反序列化选项中添加这个转换器:
var jsonOptions = new JsonSerializerOptions(); jsonOptions.Converters.Add(new BigIntegerConverter()); // 反序列化第三方API返回的JSON var model = JsonSerializer.Deserialize<YourDataModel>(apiResponse, jsonOptions); // 序列化对象时,BigInteger会自动转为JSON数值 var serializedJson = JsonSerializer.Serialize(model, jsonOptions);
方案二:利用JsonNumberHandling选项(.NET 6+)
如果项目基于.NET 6及以上版本,可通过配置JsonNumberHandling简化反序列化:
var options = new JsonSerializerOptions { NumberHandling = JsonNumberHandling.AllowOverflow }; var model = JsonSerializer.Deserialize<YourDataModel>(apiResponse, options);
注意:默认情况下System.Text.Json仍会把BigInteger序列化为字符串,若要输出数值,仍需配合方案一的自定义转换器。
方案三:临时用字符串属性中转
不想写自定义转换器的话,可在模型中新增字符串属性接收API返回的数值,再通过忽略属性映射到BigInteger:
public class YourDataModel { // 接收API返回的数值(需配置NumberHandling自动转字符串) [JsonPropertyName("space")] public string SpaceRaw { get; set; } // 实际业务使用的BigInteger属性,序列化时忽略 [JsonIgnore] public BigInteger Space => BigInteger.Parse(SpaceRaw); }
使用时需开启AllowReadingFromString选项,让System.Text.Json把JSON数值转成字符串:
var options = new JsonSerializerOptions { NumberHandling = JsonNumberHandling.AllowReadingFromString }; var model = JsonSerializer.Deserialize<YourDataModel>(apiResponse, options);
这个方案需额外维护中转属性,适合快速临时解决问题。
内容的提问来源于stack exchange,提问作者julian bechtold
相关产品推荐
相关产品推荐

