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

能否用Set方法替代JsonProperty处理API返回浮点转整数反序列化问题?

解决方案

方案1:使用自定义JsonConverter(最推荐)

这个方案从根源解决类型不匹配的问题,完全不需要额外定义中转属性,不会触发代码检查告警,可复用性也更高。

针对Newtonsoft.Json的实现

public class ForceIntFromFloatConverter : JsonConverter<int>
{
    public override int ReadJson(JsonReader reader, Type objectType, int existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        var value = Convert.ToDouble(reader.Value);
        // 校验是否为整数,避免6.1这类非整数值被强转
        if (Math.Abs(value - Math.Round(value)) > 1e-6)
        {
            throw new ArgumentException($"Tried to parse number {value} to int that is not an int.");
        }
        return (int)Math.Round(value);
    }

    public override void WriteJson(JsonWriter writer, int value, JsonSerializer serializer)
    {
        // 序列化时如果需要输出为float格式可修改此处,默认输出int即可
        writer.WriteValue(value);
    }
}

直接在业务属性上标注即可,无需其他中转属性:

[JsonProperty("Quantity")]
[JsonConverter(typeof(ForceIntFromFloatConverter))]
public int Quantity { get; set; }

针对System.Text.Json的实现

如果你使用.NET自带的System.Text.Json做序列化,转换器实现如下:

public class ForceIntFromFloatConverter : JsonConverter<int>
{
    public override int Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var value = reader.GetDouble();
        if (Math.Abs(value - Math.Round(value)) > 1e-6)
        {
            throw new ArgumentException($"Tried to parse number {value} to int that is not an int.");
        }
        return (int)Math.Round(value);
    }

    public override void Write(Utf8JsonWriter writer, int value, JsonSerializerOptions options)
    {
        writer.WriteNumberValue(value);
    }
}

属性标注改为:

[JsonPropertyName("Quantity")]
[JsonConverter(typeof(ForceIntFromFloatConverter))]
public int Quantity { get; set; }

方案2:最小改动兼容原有实现

如果你不想调整现有逻辑,只需要给私有中转属性加一个无意义的getter即可消除代码检查告警,私有属性不会对外暴露,不影响正常使用。同时注意你原有IsInt方法存在逻辑漏洞,无法正确处理负数场景,建议同步修改:

[JsonProperty("Quantity")]
private float QuantityFloat { 
    get => 0; // 加空getter消除告警,反序列化过程不会调用该getter
    set 
    {
        if (!IsInt(value))
        {
            throw new ArgumentException("Tried to parse number to Quantity that is not an int.");
        }
        Quantity = (int)value;
    }
}

public int Quantity { get; set; }

// 修复后整数校验逻辑
private static bool IsInt(float value)
{
    return Math.Abs(value - Math.Round(value)) < 1e-6;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 15:36:03