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

时间:2013-07-19 12:16:23

标签: c# json.net

我有一些.NET代码反序列化运行动态语言的JSON创建的webservice个对象。因为源是动态的,所以它有时将浮点格式的整数值序列化(例如,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<int>(s));

// throws FormatException in 4.5 only
var s = "2.0";
Console.WriteLine(JsonConvert.DeserializeObject<int>(s));

// throws FormatException in 4.5, rounds to 3 in 4.0.4
var s = "2.6";
Console.WriteLine(JsonConvert.DeserializeObject<int>(s));

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

1 个答案:

答案 0 :(得分:6)

您可以通过创建自定义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<JValue>(reader); if (jsonValue.Type == JTokenType.Float) { return (int)Math.Round(jsonValue.Value<double>()); } else if (jsonValue.Type == JTokenType.Integer) { return jsonValue.Value<int>(); } throw new FormatException(); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { throw new NotImplementedException(); } } 将处理舍入(或丢弃)小数值。它可能看起来像这样:

JsonSerializerSettings settings = new JsonSerializerSettings 
{
    Converters = new List<JsonConverter> { new CustomIntConverter() } 
};

string json = @"[2.6, 0, 4.1, 5, -3, -2.2]";

List<int> list = JsonConvert.DeserializeObject<List<int>>(json, settings);

foreach (int val in list)
{
    Console.WriteLine(val);
}

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

3
0
4
5
-3
-2

以上的输出将是:

        return (int)Math.Round(jsonValue.Value<double>());

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

        return (existingValue ?? default(int));

用这个:

0
0
0
5
-3
0

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

{{1}}