ASP.NET 5 Web API中Newtonsoft将0序列化为-0.0问题咨询
问题根源
- 按照IEEE 754浮点数标准,
double类型本身支持负零(-0.0),日常运算中负零和正零的相等判断会返回true,所以你在C#代码和数据库中校验时会认为它是普通的0,不会发现符号位的差异。 - Newtonsoft.Json序列化时会保留
double的符号位信息,所以负零会被直接序列化为-0.0输出。
解决方案
你可以根据自己的业务场景选择以下任意一种方案:
方案1:全局配置Json转换器(推荐,侵入性最低)
自定义Newtonsoft.Json的double类型转换器,序列化时自动把负零转换为正零,全局生效不需要修改业务代码:
- 先实现转换器类:
using Newtonsoft.Json; public class DoubleWithoutNegativeZeroConverter : JsonConverter<double> { public override void WriteJson(JsonWriter writer, double value, JsonSerializer serializer) { // 负零与0相等,统一输出为正零 writer.WriteValue(value == 0 ? 0d : value); } public override double ReadJson(JsonReader reader, Type objectType, double existingValue, bool hasExistingValue, JsonSerializer serializer) { if (reader.Value == null) return 0d; double val = Convert.ToDouble(reader.Value); return val == 0 ? 0d : val; } }
- 在
ConfigureServices中注册转换器:
services.AddControllersWithViews() .AddNewtonsoftJson(options => { options.SerializerSettings.Converters.Add(new DoubleWithoutNegativeZeroConverter()); });
方案2:读取数据时直接处理负零
只需要在从DataReader转换double值时加一步处理即可,可以封装一个通用转换方法:
private static double ConvertDoubleWithoutNegativeZero(object value) { double res = Convert.ToDouble(value); return res == 0 ? 0d : res; // 更简单的写法:return Convert.ToDouble(value) + 0d; 负零加0会自动转为正零 }
然后替换原来的转换代码即可:
ActualAmount = ConvertDoubleWithoutNegativeZero(dr["ActualAmount"]), // 其他double字段都用这个方法转换
方案3:替换字段类型为decimal(治本,适合业务数据场景)
如果这些字段是库存、金额等对精度要求高的业务数据,建议直接把C#实体类的字段类型从double改为decimal:
decimal类型不支持负零,不会出现当前问题- 没有浮点精度误差,更适合业务数据存储和计算
仅需要修改实体类字段类型,转换时用Convert.ToDecimal即可。
验证
任意一种方案修改完成后,再序列化输出时负零就会被替换为正常的0。
内容的提问来源于stack exchange,提问作者Ramil Aliyev 007
相关产品推荐
相关产品推荐

