我有一些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 ...
}
}