1

如何强制 NewtonSoft Json Serializer 以相同的方式序列化两个小数?

decimal a = 1234.1200M;
decimal b = 1234.12M;

var sa = JsonConvert.SerializeObject(new { value = a });
var sb = JsonConvert.SerializeObject(new {value = b});
Console.WriteLine(sa);
Console.WriteLine(sb);

结果是: {"value":1234.1200} {"value":1234.12}

如何强制它用 4 位小数对它们进行序列化,以使结果相同?

4

2 回答 2

0

您可以按如下方式格式化小数:

        var sa = JsonConvert.SerializeObject(new { value = a.ToString("#.#000") });
        var sb = JsonConvert.SerializeObject(new { value = b.ToString("#.#000") });
于 2013-08-11T07:07:46.307 回答
0

在稍微摆弄一下序列化程序后,我找到了一个“答案”:

private class JsonTextWriterOptimized : JsonTextWriter
{
    public JsonTextWriterOptimized(TextWriter textWriter)
        : base(textWriter)
    {
    }
    public override void WriteValue(decimal value)
    {
        // we really really really want the value to be serialized as "0.0000" not "0.00" or "0.0000"!
        value = Math.Round(value, 4);
        // divide first to force the appearance of 4 decimals
        value = Math.Round((((value+0.00001M)/10000)*10000)-0.00001M, 4); 
        base.WriteValue(value);
    }
}

第一个 Math.Round 将在第 4 个之后删除任何小数。值+0.00001M 完成后,像 100 这样的数字变为 100.00001。然后我们乘除。所有这一切都使小数点坚持到小数点后 4 位。然后我们将其四舍五入以确保我们通过 +0.00001 添加的第 5 位小数已消失。这似乎适用于我投入的任何价值观。

然后使用自定义编写器:

var jsonSerializer = Newtonsoft.Json.JsonSerializer.Create();
var sb = new StringBuilder(256);
var sw = new StringWriter(sb, CultureInfo.InvariantCulture);
using (var jsonWriter = new JsonTextWriterOptimized(sw))
{
    jsonWriter.Formatting = Formatting.None;
    jsonSerializer.Serialize(jsonWriter, instance);
}

我还修复了自己的答案(我忘记了类似的问题): 将小数序列化为 JSON,如何四舍五入?

于 2013-08-11T23:07:29.280 回答