.net 将NaN值序列化为JSON中的空值
大多数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安全,如果这对您很重要的话”,所以您可以这样做:.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) 显然,这不会在所有情况下都起作用,但就我们的目的而言,这是可以的。我们
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
。这破坏了我应用程序中的一个单元测试。感谢您指出这一点,但我无法再接受您的编辑(已被拒绝!?)。。。我根据你的编辑修改了答案。