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

反序列化时如何去除尾随零?如何配置该自定义行为

关于Decimal序列化/反序列化去除尾随零的解决方案

嘿,刚好之前处理过类似的需求,来给你详细说说:

一、如何实现去除尾随零(以.NET常用JSON库为例)

先澄清下:你示例里从decimal类型输出JSON,这其实是序列化过程;如果是从JSON字符串转decimal并处理尾随零,那是反序列化——两种场景我都给你覆盖到:

1. 使用Newtonsoft.Json(Json.NET)

序列化时自动去除尾随零

可以直接通过配置DecimalFormatHandling实现,或者用自定义转换器更灵活:

// 简单配置方式
var settings = new JsonSerializerSettings
{
    DecimalFormatHandling = DecimalFormatHandling.Currency,
    Formatting = Formatting.Indented // 可选,美化输出格式
};
decimal value = 1.99000m;
string json = JsonConvert.SerializeObject(value, settings);
// 输出结果:"1.99"

如果需要更精细的控制,写个自定义转换器:

public class TrimTrailingZeroDecimalConverter : JsonConverter<decimal>
{
    public override decimal ReadJson(JsonReader reader, Type objectType, decimal existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        // 反序列化场景:处理JSON字符串里的尾随零
        string strValue = reader.Value.ToString();
        var trimmed = strValue.TrimEnd('0').TrimEnd('.');
        return decimal.Parse(string.IsNullOrEmpty(trimmed) ? "0" : trimmed);
    }

    public override void WriteJson(JsonWriter writer, decimal value, JsonSerializer serializer)
    {
        // 序列化场景:把decimal转成无尾随零的字符串
        var trimmed = value.ToString().TrimEnd('0').TrimEnd('.');
        writer.WriteValue(string.IsNullOrEmpty(trimmed) ? "0" : trimmed);
    }
}

使用时在配置里添加转换器:

var settings = new JsonSerializerSettings
{
    Converters = new List<JsonConverter> { new TrimTrailingZeroDecimalConverter() }
};
string json = JsonConvert.SerializeObject(1.99000m, settings); // 输出"1.99"

2. 使用System.Text.Json(.NET Core/.NET 5+默认)

同样通过自定义转换器实现:

public class TrimTrailingZeroDecimalConverter : JsonConverter<decimal>
{
    public override decimal Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        string strValue = reader.GetString()!;
        var trimmed = strValue.TrimEnd('0').TrimEnd('.');
        return decimal.Parse(string.IsNullOrEmpty(trimmed) ? "0" : trimmed);
    }

    public override void Write(Utf8JsonWriter writer, decimal value, JsonSerializerOptions options)
    {
        var trimmed = value.ToString().TrimEnd('0').TrimEnd('.');
        writer.WriteStringValue(string.IsNullOrEmpty(trimmed) ? "0" : trimmed);
    }
}

配置并使用:

var options = new JsonSerializerOptions
{
    Converters = { new TrimTrailingZeroDecimalConverter() },
    WriteIndented = true // 可选美化输出
};
string json = JsonSerializer.Serialize(1.99000m, options); // 输出"1.99"

二、关于“去除尾随零是否是bug”的疑问

这个观点是从decimal类型的设计初衷出发的:decimal的尾随零是用来表示精度语义的——比如1.99000m意味着值精确到十万分位,而1.99m是精确到百分位,两者在业务精度要求上有细微差别。所以多数序列化库默认保留尾随零,是为了完整保留decimal的精度信息,避免丢失业务语义。

但这绝对不是“bug”!如果你的业务场景不需要这些精度标识(比如前端展示只需要简洁数值),完全可以通过上面的配置/自定义转换器实现去除尾随零的行为,这属于业务需求驱动的定制化配置,合理且完全可行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:06:19