使用Json.NET读取大整数



我有一些json与大整数,在几百位数字的顺序。我想解析为BouncyCastle的BigInteger (https://github.com/onovotny/BouncyCastle-PCL/blob/pcl/crypto/src/math/BigInteger.cs)。

{
    "bigNumber":12093812947635091350945141034598534526723049126743245...
}

所以我已经实现了一个转换器,在默认设置中使用契约解析器。

internal class BigIntegerConverter : JsonConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteRawValue(value.ToString());
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        JToken jToken = JToken.Load(reader);
        return new BigInteger(jToken.ToString());
    }
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(BigInteger));
    }
}
public class BigIntegerContractResolver : DefaultContractResolver
{
    private static readonly JsonConverter bigIntegerConverter = new BigIntegerConverter();
    private static Type type = typeof(BigInteger);
    protected override JsonConverter ResolveContractConverter(Type objectType)
    {
        if (objectType == type)
        {
            return bigIntegerConverter;
        }
        return base.ResolveContractConverter(objectType);
    }
}
JsonConvert.DefaultSettings = () => new JsonSerializerSettings
        {
            ContractResolver = new BigIntegerContractResolver()
        };

写入器正常工作,写入一个(大)整数值,而不是类BigInteger及其所有属性等。然而,阅读失败了。ReadJson和CanConvert都没有被调用。

我得到以下异常:

JsonReaderException: JSON integer 340597435091750914358634185762341897561435984635897436598435643875643189576413589743659817456…

如何获取Json。. NET解析这个数字作为一个字符串而不是一个整数?

理想情况下,我不希望自己首先解析json字符串,以添加引号。

如果你的大数没有引号,Json。Net将其反序列化为System.Numerics.BigInteger。这发生在JsonTextReader内部,在转换器有机会处理它之前。因此,如果您希望结果类型为Org.BouncyCastle.Math.BigInteger,则需要从System.Numerics.BigInteger进行转换。我知道,这似乎有点落后。另一种选择是创建自己的JsonTextReader,但这可能会带来更多的麻烦——现有读取器的大多数有用部分都在私有或内部方法中,因此将其子类化是不切实际的。

我能够让这个转换器工作:

class BigIntegerConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return (objectType == typeof(Org.BouncyCastle.Math.BigInteger));
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        System.Numerics.BigInteger big = (System.Numerics.BigInteger)reader.Value;
        return new Org.BouncyCastle.Math.BigInteger(big.ToString());
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        writer.WriteRawValue(value.ToString());
    }
}
这是我使用的测试程序。注意,我没有使用解析器。JsonSerializerSettings有一个Converters集合,所以我只是把BigIntegerConverter添加到其中。
class Program
{
    static void Main(string[] args)
    {
        string json = @"
        {
            ""bigNumber"": 12093812947635091350945141034598534526723049126743245
        }";
        JsonConvert.DefaultSettings = () => new JsonSerializerSettings
        {
            Converters = new List<JsonConverter> { new BigIntegerConverter() }
        };
        Foo foo = JsonConvert.DeserializeObject<Foo>(json);
        Console.WriteLine(foo.BigNumber.ToString());
    }
}
class Foo
{
    public Org.BouncyCastle.Math.BigInteger BigNumber { get; set; }
}
输出:

12093812947635091350945141034598534526723049126743245

您可以尝试创建处理json输出的对象:

public class YourModel
{
    [JsonConverter(typeof(CustomConverter<BigInteger>))]
    public BigInteger YourProperty{ get; set; }
}

现在它可以变得更通用的类型,你需要:

public class CustomConverter<T> : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        your code ..
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        //explicitly specify the concrete type we want to create
        return serializer.Deserialize<T>(reader);
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        your code ...
    }
}

相关内容

  • 没有找到相关文章

最新更新