在Azure APIM中使用JSON.NET反序列化时保留十进制值科学计数法格式
在Azure APIM策略表达式中保留JSON数值的科学计数法格式
问题场景
在Azure APIM策略表达式中聚合多个响应时,JSON中的十进制数值在反序列化后,序列化输出会自动转换为常规小数格式,无法保留原有的科学计数法形式。需要在不创建C#扩展或辅助方法的前提下,实现与输入一致的科学计数法数值输出。
输入示例
{ "x1": 1.55391E4, "x2": 2.2173244E5, "x3": 1.11226E3, "UpdatedDateTime": "2023-01-17T20:45:51.959+08:00" }
当前不符合预期的输出
{ "x1": 15539.1, "x2": 221732.44, "x3": 1112.26, "UpdatedDateTime": "2023-01-17T20:45:51.959+08:00" }
期望输出
{ "x1": 1.55391E4, "x2": 2.2173244E5, "x3": 1.11226E3, "UpdatedDateTime": "2023-01-17T20:45:51.959+08:00" }
解决方案
核心思路
问题根源在于默认反序列化会将科学计数法的数值解析为Decimal类型,而Decimal序列化时默认采用常规小数格式。通过调整JSON序列化/反序列化的配置,将数值解析为Double类型,利用Newtonsoft.Json对Double类型的默认序列化规则(符合条件的数值自动使用科学计数法),即可保留原格式。
策略表达式实现
在APIM的<set-body>策略中,使用以下代码处理响应:
<set-body>@{ // 读取原始响应内容 var originalContent = context.Response.Body.As<string>(); // 反序列化时指定解析为Double类型,同时保留时区偏移的DateTime格式 var jsonObject = JsonConvert.DeserializeObject<JObject>(originalContent, new JsonSerializerSettings { FloatParseHandling = FloatParseHandling.Double, DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind }); // 此处添加你的聚合逻辑,例如合并其他响应数据到jsonObject中 // ... // 序列化时保持时区偏移,并让Double类型数值自动使用科学计数法输出 return JsonConvert.SerializeObject(jsonObject, new JsonSerializerSettings { DateTimeZoneHandling = DateTimeZoneHandling.RoundtripKind, Formatting = Formatting.Indented // 保持JSON格式化排版,与示例一致 }); }</set-body>
关键点说明
FloatParseHandling.Double:强制将JSON中的数值解析为Double类型,而非默认的Decimal,确保序列化时符合科学计数法的数值会自动以该格式输出。DateTimeZoneHandling.RoundtripKind:保留原始的时区偏移信息,避免DateTime格式被修改。- 聚合逻辑兼容:如果聚合过程中涉及数值计算,需确保计算结果仍为
Double类型,否则会再次丢失科学计数法格式。
内容的提问来源于stack exchange,提问作者Abdul Wahab
相关产品推荐
相关产品推荐

