我正在使用 System.Text.Json 将 BigInteger 序列化为JSON:
I'm serialising a BigInteger to JSON using System.Text.Json:
JsonSerializer.Serialize(new {foo = new BigInteger(ulong.MaxValue) + 1})这将导致以下输出:
{"foo":{"IsPowerOfTwo":true,"IsZero":false,"IsOne":false,"IsEven":true,"Sign":1}}如果我添加一个将 BigInteger 值转换为 ulong 的转换器,则它当然会失败,因为 BigInteger 值太大:
If I add a converter that casts the BigInteger value to a ulong, it of course fails because the BigInteger value is too big:
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 .
I know this can be achieved with JsonWriter.WriteRawValue in Json.NET, but I am restricted to using System.Text.Json.
有什么方法可以做到,而无需手动破解序列化的字符串?
Is there any way to do this without manually hacking the serialised string?
推荐答案为 BigInteger 编写转换器有点尴尬,因为如您所述, Utf8JsonReader 和 Utf8JsonWriter 从.NET 5开始不提供读写原始JSON的功能.
Writing a converter for BigInteger is a little awkward because, as you note, Utf8JsonReader and Utf8JsonWriter do not provide the ability to read and write raw JSON as of .NET 5.
JsonDocument ,但是,确实通过 RootElement.GetRawText() ,因此您可以通过阅读来编写转换器像这样从中间文件中写入并写入中间文件:
JsonDocument, however, does provide access to the raw JSON via RootElement.GetRawText(), so you can write your converter by reading from and writing to an intermediate document like so:
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); } }演示小提琴此处.
更多推荐
使用System.Text.Json序列化BigInteger
发布评论