Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/json/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 将NaN值序列化为JSON中的空值_.net_Json_Serialization_Json.net_Nan - Fatal编程技术网

.net 将NaN值序列化为JSON中的空值

.net 将NaN值序列化为JSON中的空值,.net,json,serialization,json.net,nan,.net,Json,Serialization,Json.net,Nan,大多数Json解析器不会序列化NaN,因为在Javascript中,NaN不是常量。然而,Json.Net确实将NaN值序列化为NaN,这意味着它输出无效的Json;对于大多数解析器,尝试反序列化此Json将失败。(我们正在WebKit中反序列化。) 我们已经破解了Json.Net代码,在传递NaN时输出空值,但这似乎是一个糟糕的解决方案。Douglas Crockford(一次)建议使用空值代替NAN: (请看幻灯片16) 显然,这不会在所有情况下都起作用,但就我们的目的而言,这是可以的。我们

大多数Json解析器不会序列化NaN,因为在Javascript中,NaN不是常量。然而,Json.Net确实将NaN值序列化为NaN,这意味着它输出无效的Json;对于大多数解析器,尝试反序列化此Json将失败。(我们正在WebKit中反序列化。)

我们已经破解了Json.Net代码,在传递NaN时输出空值,但这似乎是一个糟糕的解决方案。Douglas Crockford(一次)建议使用空值代替NAN:

(请看幻灯片16)

显然,这不会在所有情况下都起作用,但就我们的目的而言,这是可以的。我们不想修改Json.Net的源代码。有人知道如何使用Json.Net将NaN输入转换为空输出吗?

作者希望“为float/double编写一个JsonConverter,使NaN安全,如果这对您很重要的话”,所以您可以这样做:

class LawAbidingFloatConverter : JsonConverter {
    public override bool CanRead
    {
        get
        {
            return false;
        }
    }
    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var val = value as double? ?? (double?) (value as float?);
        if (val == null || Double.IsNaN((double)val) || Double.IsInfinity((double)val))
        {
            writer.WriteNull();
            return;
        }
        writer.WriteValue((double)val);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(double) || objectType == typeof(float);
    }
}
然后使用它:

var settings = new JsonSerializerSettings();
var floatConverter = new LawAbidingFloatConverter();
settings.Converters.Add(floatConverter);
var myConverter = new JsonNetSerializer(settings);

Raphael Schweikerts解决方案,带
浮动
支持:

public class StandardFloatConverter : JsonConverter
{
    public override bool CanRead
    {
        get
        {
            return false;
        }
    }
    public override bool CanWrite
    {
        get
        {
            return true;
        }
    }
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        if (value == null)
        {
            writer.WriteNull();
            return;
        }

        var val = Convert.ToDouble(value);
        if(Double.IsNaN(val) || Double.IsInfinity(val))
        {
            writer.WriteNull();
            return;
        }
        // Preserve the type, otherwise values such as 3.14f may suddenly be
        // printed as 3.1400001049041748.
        if (value is float)
            writer.WriteValue((float)value);
        else
            writer.WriteValue((double)value);
    }
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(double) || objectType == typeof(float);
    }
}

为了将来的读者,如果您可以接受零而不是空值,那么这个问题似乎已经被解决了

序列化NaN和无穷大浮点值

Json.NET不再序列化NaN和正负无限 浮点值作为符号,这是无效的JSON。使用5.0 新的默认设置是将这些值序列化为字符串,例如“NaN” 而不是楠。序列化正常浮点值没有变化 点数

已添加FloatFormatHandling设置,以便您可以控制 NaN和无穷大值被序列化

string json;     
IList<double> d = new List<double> {1.1, double.NaN, double.PositiveInfinity};

json = JsonConvert.SerializeObject(d);

// [1.1,"NaN","Infinity"]

json = JsonConvert.SerializeObject(d, new JsonSerializerSettings {FloatFormatHandling = FloatFormatHandling.Symbol});  

// [1.1,NaN,Infinity]

json = JsonConvert.SerializeObject(d, new JsonSerializerSettings {FloatFormatHandling = FloatFormatHandling.DefaultValue});  

// [1.1,0.0,0.0]
stringjson;
IList d=新列表{1.1,double.NaN,double.PositiveInfinity};
json=JsonConvert.Serialized对象;
//[1.1,“南”,“无限”]
json=JsonConvert.Serialized对象(新JsonSerializerSettings{FloatFormatHandling=FloatFormatHandling.Symbol});
//[1.1,NaN,无穷大]
json=JsonConvert.Serialized对象(新JsonSerializerSettings{FloatFormatHandling=FloatFormatHandling.DefaultValue});
// [1.1,0.0,0.0]

不适用于
double
float
-
双精度?
始终为
null
!你说得对,它不适用于
float
s。我不太清楚为什么
(double?)。我已经用一个有效的解决方案更新了我的答案。谢谢如果为正常值保留原始行为很重要,还可以使用
If(value为float)WriteValue((float)val)替换
write.WriteValue(val)
;else writer.WriteValue((双)val)
。否则,可能会突然将
3.14f
序列化为
3.1400001049041748
,而不是
3.14
。这破坏了我应用程序中的一个单元测试。感谢您指出这一点,但我无法再接受您的编辑(已被拒绝!?)。。。我根据你的编辑修改了答案。