System.Text.Json 默认将 double 类型的值 1.0 序列化为 int 类型的值 1

Mah*_*yak 3 c# json.net asp.net-core system.text.json

我正在升级到 ASP.NET Core 3.1,在切换到 System.Text.Json 后注意到浮点值的奇怪结果变化。经过调查,我意识到 System.Text.Json 将 double 值转换为 int。例如,考虑一个简单的合约:

public class RowVector
{
    [JsonPropertyName("x")]
    public double X { get; set; }

    [JsonPropertyName("y")]
    public double Y { get; set; }

    [JsonPropertyName("z")]
    public double Z { get; set; }
}

var rowVector = new RowVector { X = 1.0, Y = 213.9, Z = 112.0 };
var serializedData = JsonSerializer.Serialize(rowVector);

Serialized-Data output with System.Text.Json :{"x":1,"y":213.9,"z":112}
Run Code Online (Sandbox Code Playgroud)

这里 x 和 z 是 int 值,而在 Newtonsoft.Json 中,

Serialized-Data output with Newtonsoft.Json :{"X":1.0,"Y":213.9,"Z":112.0}
Run Code Online (Sandbox Code Playgroud)

这里 x 和 z 保留为双精度值。

因此,对于 system.text.json,反序列化后这些值是 int,这会导致我们的处理计算发生变化,您知道为什么在 System.Text.Json 中以这种方式实现吗?

wei*_*hch 7

您所看到的是JSON 的一个已知可移植性问题

JSON 中的数字与它们在编程语言中的表示方式无关。虽然这允许序列化任意精度的数字,但它可能会导致可移植性问题。例如,由于没有分化整数和浮点值之间进行的,一些实施方式可以治疗4242.0以及4.2E+1作为相同的号码,而其他人可能不会。

另见此处

例如,基于 JavaScript 的验证器可能会接受1.0整数,而基于 Python 的 jsonschema 则不会。

因此,无论哪种方式,在 JSON 中传递数字时都会存在可移植性问题。

您始终可以拥有自己的转换器来扩展/修改序列化程序的默认行为。

  • 是的,我完全同意 JSON 可移植性问题,但如果 System.Text.Json 在框架中提供像 FloatParseHandling 这样的选项,而不是每个应用程序为 double、float 等简单数据类型编写自己的自定义转换器,那就太好了。 (2认同)