我有一些.NET代码反序列JSON化由webservice运行动态语言创建的对象.因为源是动态的,所以它有时会以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<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));
Run Code Online (Sandbox Code Playgroud)
有没有简单的方法来恢复原来的行为?理想的行为是仅反序列化具有整数值的数字,但是以任何格式(例如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<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();
}
}
Run Code Online (Sandbox Code Playgroud)
然后,您可以像这样使用自定义转换器:
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);
}
Run Code Online (Sandbox Code Playgroud)
上面的输出是这样的:
3
0
4
5
-3
-2
Run Code Online (Sandbox Code Playgroud)
如果您希望转换器忽略十进制值而不是舍入它们,请替换以下代码行
return (int)Math.Round(jsonValue.Value<double>());
Run Code Online (Sandbox Code Playgroud)
有了这个:
return (existingValue ?? default(int));
Run Code Online (Sandbox Code Playgroud)
进行更改后,上面的测试代码的输出将如下所示:
0
0
0
5
-3
0
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3880 次 |
| 最近记录: |