将 NaN 编码为 JSON
Encoding NaN to JSON
我的服务器使用 ServiceStack 生成 JSON,我需要向浏览器发送 double[]
个包含 NaN 的数组。
由于在 JSON 中没有编码 NaN 的标准方法,因此这并不奇怪
ServiceStack 在存在 NaN 时产生无效的 JSON
(例如 [0,NaN,42]
)。我选择字符串值作为 NaN 的自定义表示(顺便说一句,还有 ±Inf):
[0,"NaN",42,"Inf","-Inf"]
为例。 (当然,我也在浏览器端实现了必要的 post-处理)。
我设法通过将 JsConfig<double>.RawSerializeFn
设置为编码器函数来做到这一点。
很好,直到我意识到作为副作用的是 double
类型的所有 DTO 属性
当值为 0 时,从它们的 JSON 表示中消失。
编辑:这可以通过 new KeyValuePair<double, double>(0, 1).ToJson()
来证明
其中 returns {"Key":0,"Value":1}
当 JsConfig<double>.RawSerializeFn
未设置时,
但是 returns {"Value":1}
当设置 JsConfig<double>.RawSerializeFn
时。
此更改是我想避免的副作用。 (但我的核心问题是在不牺牲零值 DTO 属性的情况下传输 NaN 。)
我浏览了 source code
ServiceStack 并确认存在
自定义 RawSerializeFn
激活 Equals(DefaultValue,propertyValue)
检查
(通过导致 propertySuppressDefaultConfig==true
),默认情况下被省略。
AFAICS 避免此检查的唯一方法是设置 JsConfig.IncludeNullValues=true
,
这很糟糕,因为它不能仅针对 double
值完成。我需要
默认行为:省略具有 null
值的属性(对于引用类型) 和 在生成的 JSON.
中包含 0.0 双精度值
如何实现这些?
这个custom RawSerializeFn emits 0 values in the latest version of 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}
我的服务器使用 ServiceStack 生成 JSON,我需要向浏览器发送 double[]
个包含 NaN 的数组。
由于在 JSON 中没有编码 NaN 的标准方法,因此这并不奇怪
ServiceStack 在存在 NaN 时产生无效的 JSON
(例如 [0,NaN,42]
)。我选择字符串值作为 NaN 的自定义表示(顺便说一句,还有 ±Inf):
[0,"NaN",42,"Inf","-Inf"]
为例。 (当然,我也在浏览器端实现了必要的 post-处理)。
我设法通过将 JsConfig<double>.RawSerializeFn
设置为编码器函数来做到这一点。
很好,直到我意识到作为副作用的是 double
类型的所有 DTO 属性
当值为 0 时,从它们的 JSON 表示中消失。
编辑:这可以通过 new KeyValuePair<double, double>(0, 1).ToJson()
来证明
其中 returns {"Key":0,"Value":1}
当 JsConfig<double>.RawSerializeFn
未设置时,
但是 returns {"Value":1}
当设置 JsConfig<double>.RawSerializeFn
时。
此更改是我想避免的副作用。 (但我的核心问题是在不牺牲零值 DTO 属性的情况下传输 NaN 。)
我浏览了 source code
ServiceStack 并确认存在
自定义 RawSerializeFn
激活 Equals(DefaultValue,propertyValue)
检查
(通过导致 propertySuppressDefaultConfig==true
),默认情况下被省略。
AFAICS 避免此检查的唯一方法是设置 JsConfig.IncludeNullValues=true
,
这很糟糕,因为它不能仅针对 double
值完成。我需要
默认行为:省略具有 null
值的属性(对于引用类型) 和 在生成的 JSON.
如何实现这些?
这个custom RawSerializeFn emits 0 values in the latest version of 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}