升级Json.NET后如何恢复int反序列化行为?

我有一些.NET代码反序列化由运行动态语言的webservice创建的JSON对象。 因为源是动态的,所以它有时会以float格式序列化整数值(例如2被序列化为“2.0”)。

使用Json.NET 4.0.4 ,这可以无缝地工作(似乎在反序列化时应用了舍入)。 但是,升级到Json.NET 4.5后,反序列化2.0现在会抛出FormatException 。 这是代码:

 // works as expected in both versions var s = "2"; Console.WriteLine(JsonConvert.DeserializeObject(s)); // throws FormatException in 4.5 only var s = "2.0"; Console.WriteLine(JsonConvert.DeserializeObject(s)); // throws FormatException in 4.5, rounds to 3 in 4.0.4 var s = "2.6"; Console.WriteLine(JsonConvert.DeserializeObject(s)); 

有没有简单的方法来恢复原来的行为? 理想的行为是仅反序列化具有整数值的数字,但是以任何格式(例如2.0,1e10,但不是2.5),但我会满足于4.0.4行为。

您可以通过创建一个自定义JsonConverter来处理舍入(或丢弃)十进制值。 它可能看起来像这样:

 class CustomIntConverter : JsonConverter { public override bool CanConvert(Type objectType) { return (objectType == typeof(int)); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { JValue jsonValue = serializer.Deserialize(reader); if (jsonValue.Type == JTokenType.Float) { return (int)Math.Round(jsonValue.Value()); } else if (jsonValue.Type == JTokenType.Integer) { return jsonValue.Value(); } throw new FormatException(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } } 

然后,您可以像这样使用自定义转换器:

 JsonSerializerSettings settings = new JsonSerializerSettings { Converters = new List { new CustomIntConverter() } }; string json = @"[2.6, 0, 4.1, 5, -3, -2.2]"; List list = JsonConvert.DeserializeObject>(json, settings); foreach (int val in list) { Console.WriteLine(val); } 

上面的输出是这样的:

 3 0 4 5 -3 -2 

如果您希望转换器忽略十进制值而不是舍入它们,请替换以下代码行

  return (int)Math.Round(jsonValue.Value()); 

有了这个:

  return (existingValue ?? default(int)); 

进行更改后,上面的测试代码的输出将如下所示:

 0 0 0 5 -3 0