【发布时间】:2016-05-15 05:15:16
【问题描述】:
Newtonsoft 的 Json.Net 显然能够反序列化 NaN,但我似乎无法强制它在提供的浮点字段中进行。我得到一个Unexpected character "N" 异常。
在以下代码中:
using Newtonsoft.Json;
namespace TestNanDeserialize
{
public class Number
{
public float Float;
}
public class Empty
{
}
internal class Program
{
private const string testJson = "{float: NaN}";
private static void Main(string[] args)
{
Succeeds();
Fails();
}
private static void Succeeds()
{
var result = JsonConvert.DeserializeObject<Empty>(testJson);
}
private static void Fails()
{
var result = JsonConvert.DeserializeObject<Number>(testJson);
}
}
}
Succeeds() 和 Fails() 生成两个非常不同的调用堆栈:
Succeeds()
Newtonsoft.Json.dll!Newtonsoft.Json.JsonTextReader.ParseNumberNaN() Line 2299 C#
Newtonsoft.Json.dll!Newtonsoft.Json.JsonTextReader.ParseValue() Line 1572 C#
Newtonsoft.Json.dll!Newtonsoft.Json.JsonTextReader.Read() Line 381 C#
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(object newObject, Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, string id) Line 2331 C#
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, object existingValue) Line 485 C#
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, object existingValue) Line 291 C#
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(Newtonsoft.Json.JsonReader reader, System.Type objectType, bool checkAdditionalContent) Line 167 C#
Newtonsoft.Json.dll!Newtonsoft.Json.JsonSerializer.DeserializeInternal(Newtonsoft.Json.JsonReader reader, System.Type objectType) Line 823 C#
Newtonsoft.Json.dll!Newtonsoft.Json.JsonSerializer.Deserialize(Newtonsoft.Json.JsonReader reader, System.Type objectType) Line 802 C#
Newtonsoft.Json.dll!Newtonsoft.Json.JsonConvert.DeserializeObject(string value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) Line 863 C#
Newtonsoft.Json.dll!Newtonsoft.Json.JsonConvert.DeserializeObject<TestNanDeserialize.Empty>(string value, Newtonsoft.Json.JsonSerializerSettings settings) Line 820 C#
Newtonsoft.Json.dll!Newtonsoft.Json.JsonConvert.DeserializeObject<TestNanDeserialize.Empty>(string value) Line 757 C#
TestNanDeserialize.exe!TestNanDeserialize.Program.Succeeds() Line 26 C#
TestNanDeserialize.exe!TestNanDeserialize.Program.Main(string[] args) Line 20 C#
Fails()
Newtonsoft.Json.dll!Newtonsoft.Json.JsonTextReader.ReadAsDouble() Line 948 C#
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.ReadForType(Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonContract contract, bool hasConverter) Line 2214 C#
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.PopulateObject(object newObject, Newtonsoft.Json.JsonReader reader, Newtonsoft.Json.Serialization.JsonObjectContract contract, Newtonsoft.Json.Serialization.JsonProperty member, string id) Line 2359 C#
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateObject(Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, object existingValue) Line 485 C#
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.CreateValueInternal(Newtonsoft.Json.JsonReader reader, System.Type objectType, Newtonsoft.Json.Serialization.JsonContract contract, Newtonsoft.Json.Serialization.JsonProperty member, Newtonsoft.Json.Serialization.JsonContainerContract containerContract, Newtonsoft.Json.Serialization.JsonProperty containerMember, object existingValue) Line 291 C#
Newtonsoft.Json.dll!Newtonsoft.Json.Serialization.JsonSerializerInternalReader.Deserialize(Newtonsoft.Json.JsonReader reader, System.Type objectType, bool checkAdditionalContent) Line 167 C#
Newtonsoft.Json.dll!Newtonsoft.Json.JsonSerializer.DeserializeInternal(Newtonsoft.Json.JsonReader reader, System.Type objectType) Line 823 C#
Newtonsoft.Json.dll!Newtonsoft.Json.JsonSerializer.Deserialize(Newtonsoft.Json.JsonReader reader, System.Type objectType) Line 802 C#
Newtonsoft.Json.dll!Newtonsoft.Json.JsonConvert.DeserializeObject(string value, System.Type type, Newtonsoft.Json.JsonSerializerSettings settings) Line 863 C#
Newtonsoft.Json.dll!Newtonsoft.Json.JsonConvert.DeserializeObject<TestNanDeserialize.Number>(string value, Newtonsoft.Json.JsonSerializerSettings settings) Line 820 C#
Newtonsoft.Json.dll!Newtonsoft.Json.JsonConvert.DeserializeObject<TestNanDeserialize.Number>(string value) Line 757 C#
TestNanDeserialize.exe!TestNanDeserialize.Program.Fails() Line 31 C#
TestNanDeserialize.exe!TestNanDeserialize.Program.Main(string[] args) Line 21 C#
您可能认为这应该足以调试它,也许它应该,但它实际上并没有让我明白在所有这些层中应该发生哪些不同的分叉以使其工作。
编辑:是的,我知道未引用的 NaN 不是有效的 JSON。 Json.Net 的一个声明特性是支持 NaN。正如上面的代码所示,它显然能够反序列化它。但是,我不确定它是否可以反序列化为浮点字段。
注意:我已经为此打开了一个缺陷:https://github.com/JamesNK/Newtonsoft.Json/issues/908
【问题讨论】:
-
“Newtonsoft 的 Json.Net 显然能够反序列化 NaN”。我不会这么认为。
NaN不是 JSON 规范的一部分。因此,您发布的示例实际上不是有效的 JSON。 -
@Andrew:我知道它不是有效的 JSON。然而它经常被使用。您的评论与我关于 Json.Net 显然能够做到这一点的声明无关,我什么也没做。我的陈述是基于事实的,正如我上面提供的代码所示。谢谢。
标签: json.net