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

使用JsonConverter序列化含NaN的double时遇ArgumentException问题求助

解决方案:自定义JsonConverter中高效处理NaN/Infinity序列化

问题根源

全局配置的JsonNumberHandling.AllowNamedFloatingPointLiterals仅对System.Text.Json的默认序列化逻辑生效。当你在自定义JsonConverter中直接调用Utf8JsonWriter.WriteNumberValue时,该方法会严格遵循JSON规范,直接拒绝NaN、正负无穷这类非标准数值,完全忽略全局配置。

高效实现方案

在自定义转换器的Write方法中,提前判断double值的类型,针对NaN/正负无穷直接写入对应的命名浮点字面量,避免字符串转换的额外开销。使用Utf8JsonWriter.WriteRawValue直接写入原生JSON字面量,性能远优于先转字符串再序列化的方式。

修改后的转换器代码:

public class SubConvertor : JsonConverter<Subclass>
{
    public override Subclass Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        return new Subclass();
    }

    public override void Write(Utf8JsonWriter writer, Subclass value, JsonSerializerOptions options)
    {
        writer.WriteStringValue("NaaaN");
        
        double num = value.NaN;
        if (double.IsNaN(num))
        {
            writer.WriteRawValue("NaN");
        }
        else if (double.IsPositiveInfinity(num))
        {
            writer.WriteRawValue("Infinity");
        }
        else if (double.IsNegativeInfinity(num))
        {
            writer.WriteRawValue("-Infinity");
        }
        else
        {
            writer.WriteNumberValue(num);
        }
    }
}

可选:联动全局配置

如果需要和全局的JsonNumberHandling配置保持一致,可以增加判断逻辑,仅当配置允许时才写入命名浮点字面量:

public override void Write(Utf8JsonWriter writer, Subclass value, JsonSerializerOptions options)
{
    writer.WriteStringValue("NaaaN");
    
    double num = value.NaN;
    bool allowNamedLiterals = (options.NumberHandling & JsonNumberHandling.AllowNamedFloatingPointLiterals) != 0;
    
    if (allowNamedLiterals)
    {
        if (double.IsNaN(num))
        {
            writer.WriteRawValue("NaN");
            return;
        }
        else if (double.IsPositiveInfinity(num))
        {
            writer.WriteRawValue("Infinity");
            return;
        }
        else if (double.IsNegativeInfinity(num))
        {
            writer.WriteRawValue("-Infinity");
            return;
        }
    }
    
    // 不允许则使用默认方法(会抛出异常,或根据需求自定义降级处理)
    writer.WriteNumberValue(num);
}

内容的提问来源于stack exchange,提问作者Liviu Sosu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 03:27:31