使用Newtonsoft Json将double.NaN反序列化为null的简便方案咨询
问题背景
现有如下类定义:
public class Foo { public double? Bar { get; set; } }
序列化时配置FloatFormatHandling.DefaultValue可将double.NaN转为null,运行符合预期,代码如下:
var foo = new Foo { Bar = double.NaN }; var test = JsonConvert.SerializeObject(foo, new JsonSerializerSettings { FloatFormatHandling = FloatFormatHandling.DefaultValue }); // 运行结果:{"Bar":null} 符合预期
但使用相同配置反序列化时无法将NaN转为null,问题复现代码如下:
var test2 = JsonConvert.SerializeObject(foo); // 运行结果:{"Bar":"NaN"} var test3 = JsonConvert.DeserializeObject<Foo>(test2, new JsonSerializerSettings { FloatFormatHandling = FloatFormatHandling.DefaultValue }); // 运行结果:test3.Bar = NaN 不符合预期,期望得到null
解决方案
FloatFormatHandling配置仅作用于序列化阶段,反序列化阶段不生效,无需自定义JsonConverter的简便实现方案如下:
方案1:修改属性setter逻辑(最简便)
直接在实体类的属性赋值阶段做NaN校验,自动转换为null,不需要修改任何序列化配置:
public class Foo { private double? _bar; public double? Bar { get => _bar; set => _bar = double.IsNaN(value ?? 0) ? null : value; } }
方案2:使用反序列化回调(无需修改属性定义)
如果不想改动原有实体类的属性定义,可以在实体类中添加反序列化完成后的回调方法,统一处理NaN值:
public class Foo { public double? Bar { get; set; } [OnDeserialized] internal void OnDeserializedMethod(StreamingContext context) { if (double.IsNaN(Bar ?? 0)) { Bar = null; } } }
内容的提问来源于stack exchange,提问作者John
相关产品推荐
相关产品推荐

