`JsonConvert.DeserializeObject <model>(“{float:NaN}”)`失败

时间:2016-01-28 16:06:23

标签: json.net

Newtonsoft的Json.Net显然能够反序列化NaN,但我似乎无法将其强制转换为提供的浮点字段。我得到ImportError: No module named 'extra_views'例外。

在以下代码中:

docker-compose django run pip freeze

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#

您可能认为应该足以进行调试,也许应该这样,但实际上并没有让我明白在所有这些层中应该以不同的方式使用它以使其工作。

编辑:是的,我知道不带引号的NaN不是有效的JSON。 Json.Net的一个明确特征是支持NaN。它显然能够反序列化,如上面的代码所示。但是,我不确定它是否可以反序列化为浮点字段。

注意:我在https://github.com/JamesNK/Newtonsoft.Json/issues/908

打开了一个缺陷

1 个答案:

答案 0 :(得分:4)

您遇到困难的原因是您的JSON is invalid - 特别是符号NaN需要引用。即可以将以下JSON反序列化到您的Number类:

{"float": "NaN"}

以下不能:

{float: NaN}

请注意,有一个设置FloatFormatHandling.Symbol,允许NaN输出不带引号,因此可能是早期版本的Json.NET能够解析未引用的NaN }字符串为floatdouble。但目前情况似乎并非如此。请参阅Serializing NaN results in non-JSON compliant textJson.NET 5.0 Release 1: Serializing NaN and Infinity Floating Point Values

更新2

我尝试在不同版本的Json.NET中反序列化未加引号的JSON字符串{float: NaN}

  • 8.0.2(当前):失败。
  • 7.0.1:成功。
  • 3.5:成功。

所以这可能是回归。您可能需要report an issue

<强>更新

正如@shannon所指出的那样,JSON.NET对JSON标准的扩展存在不一致。 JToken.Parse("NaN")返回类型为JValue的{​​{1}},但Float会引发异常。可以使用此不一致性来编写处理非引用JsonConvert.DeserializeObject<double>("NaN")字符串的转换器:

NaN