【问题标题】:Prevent NewtonSoft Json from adding trailing 0 [duplicate]防止 NewtonSoft Json 添加尾随 0 [重复]
【发布时间】:2020-12-01 15:33:30
【问题描述】:

我遇到了NewtonSoft.Json 库的意外问题。它似乎在没有小数部分的十进制值中添加了尾随 0:

JsonConvert.SerializeObject(1m)

将返回以下字符串:"1.0"

虽然在很多情况下这不是问题,但就我而言,我确实关心用户提供的精度。如果用户输入1,我需要将1 存储在我的数据库中。如果他提供1.0,那么我需要存储1.0

我正在使用库的最后一个版本:12.0.3,但我尝试使用所有以前的主要版本到9.0.1,它们都产生相同的结果。

我看到了几个关于库删除尾随 0 的问题(报告为错误,已在版本 11.X 中修复),但没有关于添加一个。

这是我应该报告的错误吗? 如何覆盖此默认行为?

【问题讨论】:

  • 字符串很可能是1.0 而不是"1.0"。如果是1.0,那么它只是一个数字,添加尾随零对 JSON 的反序列化方式没有影响。
  • 那你不就是想把你的值存储为字符串吗?
  • 您问“为什么图书馆要增加该领域的精度?”。它不是库,而是 Javascript(JSON 是基于它的)。 C# 有多种数字类型(int、float、double、decimal)。 Javascript 有一个:number。 Javascript 数字可以表示整数或包含小数位的数字;它不在乎。在 Javascript 中,("1.0" == 1) 表达式实际上会计算为 true(Javascript 可以非常宽容)。
  • 这是设计使然,请参阅Decimal with no decimal point serialized as a Decimal with a decimal point #590。我相信 Newtonsoft 这样做是因为,在 JSON spec 中,小数点后没有数字的 JSON 文字(例如 1.)格式不正确,因此选择 1.0 而不是 1 来暗示该值是小数/double 不是整数。如上面的 cmets 和下面的答案所述,自定义转换器可以覆盖此设计决策。

标签: c# json.net


【解决方案1】:

这不是错误,这是库的工作方式。如果您想覆盖此行为,您将需要一个自定义类型转换器,例如:

public class DecimalJsonConverter : JsonConverter<decimal>
{
    public override decimal ReadJson(JsonReader reader, Type objectType, 
        decimal existingValue, bool hasExistingValue, JsonSerializer serializer)
    {
        throw new NotImplementedException();
    }

    public override void WriteJson(JsonWriter writer, 
        decimal value, JsonSerializer serializer)
    {
        // Customise how you want the decimal value to be output in here
        // for example, you may want to consider culture
        writer.WriteRawValue(value.ToString());
    }
}

现在像这样序列化:

var settings = new JsonSerializerSettings
{
    Converters = new[] { new DecimalJsonConverter() }
};

var json = JsonConvert.SerializeObject(1m, settings);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-21
    • 2021-11-03
    • 2017-05-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多