带有system.text.json的大整数

7gyucuyw  于 2023-03-04  发布在  其他
关注(0)|答案(1)|浏览(177)

我正在从一个我无法控制的公共API中提取数据。
一个对象包含属性"space":40110198681182961664。此属性对于ulong来说太大。
正确的值类型应该是BigInteger。问题来了。System.Text.Json只能将BigIntegers序列化为string或从string序列化,例如:"space":"40110198681182961664"
我尝试过其他选项,比如序列化为字符串,但是system.text.json不会将数值序列化为字符串。
用system.text.json序列化/反序列化这个值有哪些选项?

e5njpo68

e5njpo681#

实现自定义值转换器

首先,添加一个能够读取原始值并转换为目标类型的类:

using System.Numerics;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;

public class BigIntegerConverter : JsonConverter<BigInteger>
{
    /// <summary>
    /// Converts a JSON value to a <see cref="BigInteger"/>.
    /// </summary>
    /// <param name="reader">The <see cref="Utf8JsonReader"/> to read from.</param>
    /// <param name="typeToConvert">The type of the object to convert.</param>
    /// <param name="options">The serializer options to use.</param>
    /// <returns>The converted <see cref="BigInteger"/>.</returns>
    public override BigInteger Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // Check if the input is a numeric value
        if (reader.TokenType == JsonTokenType.Number)
        {
            // Try to parse the input directly as a BigInteger using Utf8Parser
            ReadOnlySpan<byte> span = reader.ValueSpan;
            string stringValue = Encoding.UTF8.GetString(span);
            if (BigInteger.TryParse(stringValue, out BigInteger result))
            {
                return result;
            }
        }
        // Check if the input is a string value
        else if (reader.TokenType == JsonTokenType.String)
        {
            // Try to parse the input as a BigInteger using BigInteger.TryParse
            if (BigInteger.TryParse(reader.GetString(), out BigInteger result))
            {
                return result;
            }
        }

        // If parsing fails, throw a JsonException
        throw new JsonException($"Could not convert \"{reader.GetString()}\" to BigInteger.");
    }

    /// <summary>
    /// Writes a <see cref="BigInteger"/> value as a JSON number.
    /// </summary>
    /// <param name="writer">The <see cref="Utf8JsonWriter"/> to write to.</param>
    /// <param name="value">The value to write.</param>
    /// <param name="options">The serializer options to use.</param>
    public override void Write(Utf8JsonWriter writer, BigInteger value, JsonSerializerOptions options)
    {
        // Convert the BigInteger value to a byte array using UTF8 encoding
        byte[] bytes = Encoding.UTF8.GetBytes(value.ToString());

        // Write the byte array as a raw JSON numeric value (without quotes)
        writer.WriteRawValue(Encoding.UTF8.GetString(bytes));
    }
}

接下来将自定义转换器添加到您的JsonSerializerOptions

var options = new JsonSerializerOptions();
    options.Converters.Add(new BigIntegerConverter());
return JsonSerializer.Deserialize<T>(inputString);

最后,您需要在类中标记应该被序列化/反序列化的变量:

[JsonConverter(typeof(BigIntegerConverter))] //<<-
public BigInteger space { get; set; }

相关问题