You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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类型转换器,序列化时自动把负零转换为正零,全局生效不需要修改业务代码:

  1. 先实现转换器类:
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;
    }
}
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.29 20:09:01