ACK*_*low 8 .net serialization json nan json.net
大多数Json解析器不会序列化NaN,因为在Javascript中,NaN不是常量.但是,Json.Net确实将NaN值序列化为NaN,这意味着它输出无效的Json; 试图反序列化这个Json将失败大多数解析器.(我们在WebKit中进行反序列化.)
我们已经攻击了Json.Net代码,在传递NaN时输出空值,但这似乎是一个糟糕的解决方案.Douglas Crockford(曾经)建议使用空值代替NaN:
http://www.json.org/json.ppt (见幻灯片16)
显然,这并不适用于所有情况,但它可以用于我们的目的.我们只是不必修改Json.Net的源代码.有谁知道如何使用Json.Net将NaN输入转换为空输出?
作者建议我们 "写一个JsonConverter for float/double以使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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后使用它:
var settings = new JsonSerializerSettings();
var floatConverter = new LawAbidingFloatConverter();
settings.Converters.Add(floatConverter);
var myConverter = new JsonNetSerializer(settings);
Run Code Online (Sandbox Code Playgroud)
为了未来的读者,如果您可以接受零而不是 null ,那么Json.Net似乎已经解决了这个问题。
序列化 NaN 和无穷大浮点值
Json.NET 不再将 NaN 和正负无穷浮点值序列化为符号,这是无效的 JSON。在 5.0 中,新的默认设置是将这些值序列化为字符串,例如“NaN”而不是 NaN。序列化普通浮点数没有变化。
添加了 FloatFormatHandling 设置,以便您可以控制 NaN 和无穷大值的序列化方式。
Run Code Online (Sandbox Code Playgroud)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]
Raphael Schweikerts float支持的解决方案:
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);
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5743 次 |
| 最近记录: |