I'm serialising a BigInteger
to JSON using System.Text.Json
:
JsonSerializer.Serialize(new {foo = new BigInteger(ulong.MaxValue) + 1})
This results in the following output:
{"foo":{"IsPowerOfTwo":true,"IsZero":false,"IsOne":false,"IsEven":true,"Sign":1}}
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);
This is the converter:
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);
}
The output I want is:
{"foo":18446744073709551616}
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?
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
, 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);
}
}
Demo fiddle here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With