使用System.Text.Json序列化BigInteger [英] Serialising BigInteger using System.Text.Json

查看:110
本文介绍了使用System.Text.Json序列化BigInteger的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 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 编写转换器有点尴尬,因为如您所述, 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 ,但是,确实通过

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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆