我有一些巨大整数的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整数340597435091750914358634185762341897561435984635897436598435643875643189576413589743659817456 ...对于Int64来说太大或太小。
如何让Json.NET将此数字解析为字符串而不是整数?
理想情况下,我不想首先自己解析json字符串,以添加引号。
答案 0 :(得分:3)
如果没有引用您的大号,Json.Net会将其反序列化为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
输出:
private void tabControl1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
Application.Exit();
}
else
{
}
}
答案 1 :(得分:1)
您可以尝试创建处理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 ...
}
}