如何使用ServiceStack JsonSerializer正确解析JSON小数

本文关键字:JSON 小数 何使用 ServiceStack JsonSerializer | 更新日期: 2023-09-27 18:32:02

我有以下情况:

var json = "{'"AccruedInterest'":9.16666666666666E-6}";
var result = JsonSerializer.DeserializeFromString<MyResult>(json);
Assert.That(result .AccruedInterest, Is.GreaterThan(0m));

其中MyResult将字段AccruedInterest声明为decimal

上述测试设置为 AccruedInterest 为 0,因此失败。如果我将 JSON 设置为除带有指数的应计利息值以外的任何值,则测试有效。

将 JSON 字符串转换为小数的 ServiceStack JSON 处理是否损坏?以上似乎是完全有效的JSON(使用指数等)

如何使用ServiceStack JsonSerializer正确解析JSON小数

如果将

MyResult类的类型切换到float,您将获得预期的结果:

public class Program
{
    public static void Main(string[] args)
    {
        const string json = "{'"AccruedInterest'":9.16666666666666E-6}";
        var result = JsonSerializer.DeserializeFromString<MyResult>(json);
    }
}
public class MyResult
{
    public float AccruedInterest { get; set; }
}

其原因可以在 DeserializeBuiltin 中找到:

if (typeof(T) == typeof(decimal))
    return value => decimal.Parse(value, CultureInfo.InvariantCulture);

如果您尝试自己进行解析,您将获得无效的格式异常。

decimal.Parse("9.16666666666666E-6", CultureInfo.InvariantCulture);

如果将数字样式指定为 float,则异常将消失。

decimal.Parse("9.16666666666666E-6", NumberStyles.Float, CultureInfo.InvariantCulture);

同样,将其解析为浮点数也有效:

float.Parse("9.16666666666666E-6", CultureInfo.InvariantCulture);