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

ASP.NET Core 7中System.Text.Json序列化double位数异常问题咨询

System.Text.Json序列化double位数不一致的原因及解决方案

这是预期行为,不是Bug,核心原因和浮点数的本质、System.Text.Json的序列化策略有关:

为什么会出现位数差异?

  • 64位double类型的有效精度是15-17位十进制数字,但绝大多数十进制小数无法被二进制浮点数精确表示。System.Text.Json序列化double时,会输出能还原回原始double值的最短十进制字符串——只要两个不同的十进制字符串对应的二进制double完全相同,就会选择更短的那个。
  • 你遇到的例子:内存中的6.5784774568779181和序列化后的6.578477456877918,本质是同一个double值的不同十进制写法;99.999999999999986和99.99999999999999也是如此,反序列化后都会得到内存里的原始值,不存在数据丢失。

和WCF序列化差异的原因

WCF默认使用的DataContractJsonSerializer采用了不同的输出策略:它会固定输出17位有效数字的字符串,哪怕其中包含冗余的尾数位。这种差异只是字符串表示形式不同,对应的实际double值完全一致。

修改NumberHandling无效的原因

JsonNumberHandling配置项主要控制:是否允许序列化NaN/Infinity等特殊浮点值、是否将数字序列化为字符串、是否禁止非标准数字格式。它不会改变System.Text.Json生成double十进制字符串的位数策略,所以修改后问题依旧。

如何和WCF输出保持一致?

如果需要严格对齐WCF的字符串输出格式,可以自定义一个JsonConverter<double>,强制输出17位有效数字:

public class DoubleConverter : JsonConverter<double>
{
    public override double Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return reader.GetDouble();
    }

    public override void Write(Utf8JsonWriter writer, double value, JsonSerializerOptions options)
    {
        // 使用G17格式输出17位有效数字,确保和WCF对齐
        writer.WriteStringValue(value.ToString("G17", System.Globalization.CultureInfo.InvariantCulture));
    }
}

然后将这个转换器添加到序列化配置中:

builder.Services.AddControllers()
    .AddJsonOptions(o =>
    {
        o.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter());
        o.JsonSerializerOptions.DefaultIgnoreCondition = JsonIgnoreCondition.WhenWritingNull;
        o.JsonSerializerOptions.NumberHandling = JsonNumberHandling.AllowNamedFloatingPointLiterals;
        // 添加自定义double转换器
        o.JsonSerializerOptions.Converters.Add(new DoubleConverter());
    });

如果需要和WCF一样将数字作为字符串输出(而非数字类型),可以保留NumberHandling = JsonNumberHandling.WriteAsString,配合上述转换器即可。

内容的提问来源于stack exchange,提问作者Emanuil Boyanov

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 08:33:26