将NaN编码为JSON

时间:2015-01-09 21:01:03

标签: json servicestack

我的服务器使用ServiceStack生成JSON,我需要将包含NaN的double[]数组发送到浏览器。
由于在JSON中没有标准的编码NaN的方法,所以这并不奇怪 ServiceStack在存在NaN的情况下生成无效的JSON (例如[0,NaN,42])。我选择字符串值作为我的NaN的自定义表示(顺便说一下±Inf): 以[0,"NaN",42,"Inf","-Inf"]为例。 (当然我也在浏览器端实现了必要的后处理。) 我设法通过将JsConfig<double>.RawSerializeFn设置为编码器功能来实现。 这很好,直到我意识到作为副作用的double类型的所有DTO属性 当值为0时,它们从JSON表示中消失。

编辑:这可以通过new KeyValuePair<double, double>(0, 1).ToJson()来证明 在{"Key":0,"Value":1}未设置时返回JsConfig<double>.RawSerializeFn, 但设置{"Value":1}时会返回JsConfig<double>.RawSerializeFn 这种变化是我想避免的副作用。 (但我的核心问题是在没有牺牲零值DTO属性的情况下传输NaNs 。)

我浏览了source code ServiceStack和它确认存在 自定义RawSerializeFn会激活Equals(DefaultValue,propertyValue)支票 (通过导致propertySuppressDefaultConfig==true),默认省略 AFAICS避免此检查的唯一方法是设置JsConfig.IncludeNullValues=true, 这是不好的,因为它只能用于double值。我需要的 默认行为:省略具有null值的属性(对于引用类型)在生成的JSON中包含0.0个double值。

如何实现这些目标?

1 个答案:

答案 0 :(得分:1)

最新版custom RawSerializeFn emits 0 values

中的ServiceStack.Text
JsConfig<double>.IncludeDefaultValue = true;
JsConfig<double>.RawSerializeFn = d =>
    double.IsPositiveInfinity(d) ?
        "\"+Inf\""
    : double.IsNegativeInfinity(d) ?
        "\"-Inf\""
    : double.IsNaN(d) ?
        "\"NaN\""
    : d.ToString();

var doubles = new[] { 
    0.0, 1.0, double.NegativeInfinity, double.NaN, double.PositiveInfinity };

doubles.ToJson().Print(); // [0,1,"-Inf","NaN","+Inf"]

new KeyValuePair<double, double>(0, 1).ToJson().Print(); // {"Key":0,"Value":1}