我想将包含长十进制值的JSON反序列化为自定义类型,以保持其精度(即自定义BigDecimal类)。我用的是Json。。NET 9.0.1和。NET 4.6.1。我尝试过使用JsonConverter,但似乎ReadJson调用时可用的值已经被Json识别和读取。.NET作为。NET十进制类型,并受其精度的限制。
理想情况下,我可以访问原始字符串,以便将其放入自定义类型中。我可以在目标对象上使用字符串属性,它会反序列化整个字符串,但随后我必须进一步处理对象(即,将其复制到另一种表示中),这在大型模式中尤其混乱。
有更好的方法吗?
目标类:
public class DecimalTest
{
public string stringValue { get; set; }
public decimal decimalValue { get; set; }
public BigDecimal bigDecimalValue { get; set; }
}
下面是一个JSON测试:
[TestMethod]
public void ReadBigDecimal_Test()
{
var json = @"{
""stringValue"" : 0.0050000012852251529693603515625,
""decimalValue"" : 0.0050000012852251529693603515625,
""bigDecimalValue"" : 0.0050000012852251529693603515625
}";
var settings = new JsonSerializerSettings();
settings.FloatParseHandling = FloatParseHandling.Decimal;
settings.Converters.Add(new JsonBigDecimalConverter());
var result = JsonConvert.DeserializeObject<DecimalTest>(json, settings);
Assert.IsNotNull(result);
Assert.AreEqual("0.0050000012852251529693603515625", result.stringValue);
Assert.AreEqual(0.0050000012852251529693603516m, result.decimalValue);
// *** This case fails ***
Assert.AreEqual("0.0050000012852251529693603515625", result.bigDecimalValue.ToString());
}
下面是自定义转换器:
public class JsonBigDecimalConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return (objectType == typeof(BigDecimal));
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// *** reader.Value here already appears to be a .NET decimal.
// *** If I had access to the raw string I could get this to work.
return BigDecimal.Parse(reader.Value.ToString());
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
您是否可以尝试以下
ReadJson
的实现是否如您期望的那样工作:
public override object ReadJson(
JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var token = JToken.Load(reader);
return BigDecimal.Parse(token.ToString());
}
不幸的是,上面的方法不起作用。似乎没有办法从JSON数据中读取原始字符串。
还要注意,在我的测试中,对stringValue
的断言首先失败。查看这个工作示例:https://dotnetfiddle.net/s0pqg3
我想这是因为Json。NET内部立即根据指定的FloatParseHandling
解析遇到的任何number
令牌。原始数据永远不会被保留。
我认为唯一的解决方案是将大的十进制字符串用引号括起来,像这样:
"bigDecimalValue" : "0.0050000012852251529693603515625"
下面是一个工作示例,它正是这样做的,以保持所需的精度:https://dotnetfiddle.net/U1UG3z