gpt4 book ai didi

json.net - `JsonConvert.DeserializeObject("{ float : NaN} ")` fails

转载 作者:行者123 更新时间:2023-12-01 00:45:12 25 4
gpt4 key购买 nike

Newtonsoft 的 Json.Net 显然能够反序列化 NaN,但我似乎无法将其强制执行到提供的浮点字段中。我得到一个 Unexpected character "N"异常(exception)。

在以下代码中:

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#

你可能认为这应该足以调试这个,也许它应该,但它实际上并没有让我明白在所有这些层中应该发生什么不同的 fork 以使其工作。

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

注意:我已经为此打开了一个缺陷: https://github.com/JamesNK/Newtonsoft.Json/issues/908

最佳答案

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

{"float": "NaN"}

并且以下不能:
{float: NaN}

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

更新 2

我尝试反序列化未加引号的 JSON 字符串 {float: NaN}在 Json.NET 的各种版本中:
  • 8.0.2(当前):失败。
  • 7.0.1:成功。
  • 3.5:成功。

  • 所以这可能是一种回归。您可能想要 report an issue .

    更新

    正如@shannon 所指出的,Json.NET 对 JSON 标准的扩展存在不一致之处。 JToken.Parse("NaN")返回 JValue类型 Float ,但是 JsonConvert.DeserializeObject<double>("NaN")抛出异常。可以使用这种不一致来编写处理非引用 NaN 的转换器字符串:
    public class FloatNanConverter : JsonConverter
    {
    public override bool CanConvert(Type objectType)
    {
    return objectType == typeof(float) || objectType == typeof(float?);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
    if (reader.TokenType == JsonToken.Null)
    return null;
    var value = JValue.Load(reader);
    if (objectType == typeof(float?))
    return (float?)value;
    else
    return (float)value;
    }

    public override bool CanWrite { get { false; } }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
    throw new NotImplementedException();
    }
    }

    关于json.net - `JsonConvert.DeserializeObject<Model>("{ float : NaN} ")` fails,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35066308/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com