使用 System.Text.Json 序列化 BigInteger
Posted
技术标签:
【中文标题】使用 System.Text.Json 序列化 BigInteger【英文标题】:Serialising BigInteger using System.Text.Json 【发布时间】:2021-02-23 13:42:52 【问题描述】:我正在使用 System.Text.Json
将 BigInteger
序列化为 JSON:
JsonSerializer.Serialize(new foo = new BigInteger(ulong.MaxValue) + 1)
这会产生以下输出:
"foo":"IsPowerOfTwo":true,"IsZero":false,"IsOne":false,"IsEven":true,"Sign":1
如果我添加一个将BigInteger
值转换为ulong
的转换器,它当然会失败,因为BigInteger
值太大:
var options = new JsonSerializerOptions();
options.Converters.Add(new BigIntegerConverter());
JsonSerializer.Serialize(new foo = new BigInteger(ulong.MaxValue) + 1, options);
这是转换器:
public class BigIntegerConverter : JsonConverter<BigInteger>
public override BigInteger Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) => throw new NotImplementedException();
public override void Write(Utf8JsonWriter writer, BigInteger value, JsonSerializerOptions options) => writer.WriteNumberValue((ulong)value);
我想要的输出是:
"foo":18446744073709551616
我知道这可以在 Json.NET 中使用 JsonWriter.WriteRawValue
来实现,但我仅限于使用 System.Text.Json
。
有什么方法可以在不手动破解序列化字符串的情况下做到这一点?
【问题讨论】:
【参考方案1】:为BigInteger
编写转换器有点尴尬,因为如您所见,Utf8JsonReader
和 Utf8JsonWriter
从 .NET 5 开始不提供读取和写入原始 JSON 的能力。
JsonDocument
,但是,确实通过RootElement.GetRawText()
提供对原始 JSON 的访问,因此您可以通过读取和写入中间文档来编写转换器,如下所示:
public class BigIntegerConverter : JsonConverter<BigInteger>
public override BigInteger Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
if (reader.TokenType != JsonTokenType.Number)
throw new JsonException(string.Format("Found token 0 but expected token 1", reader.TokenType, JsonTokenType.Number ));
using var doc = JsonDocument.ParseValue(ref reader);
return BigInteger.Parse(doc.RootElement.GetRawText(), NumberFormatInfo.InvariantInfo);
public override void Write(Utf8JsonWriter writer, BigInteger value, JsonSerializerOptions options)
var s = value.ToString(NumberFormatInfo.InvariantInfo);
using var doc = JsonDocument.Parse(s);
doc.WriteTo(writer);
演示小提琴here.
【讨论】:
以上是关于使用 System.Text.Json 序列化 BigInteger的主要内容,如果未能解决你的问题,请参考以下文章
使用 System.Text.Json 序列化 BigInteger
使用 System.Text.Json 使用动态键查询或反序列化 json