我使用Azure APIM策略表达式来聚合多个响应。在响应中有一些十进制值。但是在反序列化过程中,格式发生了更改,如输出所示。我想返回Input
输入>{
"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"
}
这是我的小提琴
在这个示例中,我保留了带有Offset的DateTimeZone。但我不能处理十进制字段(x1 x2 x3)我只是想像输入一样返回。请注意,我是在一个策略表达式中写的,所以我不能创建任何c#扩展或帮助方法。
在JToken
层次结构中强制使用decimal
值的科学符号的一种方法是用适当格式的JRaw
值替换十进制值的JValue
标记:
var settings = new JsonSerializerSettings
{
// Make sure that FloatParseHandling is consistent with the later check ".Where(v => v.Value is decimal)"
FloatParseHandling = FloatParseHandling.Decimal,
FloatFormatHandling = FloatFormatHandling.DefaultValue,
// Instead of DateParseHandling.DateTimeOffset, you could use DateParseHandling.None to skip DateTime recognition and leave date/time strings unchanged.
DateParseHandling = DateParseHandling.DateTimeOffset,
DateTimeZoneHandling = DateTimeZoneHandling.Unspecified
};
var obj = JsonConvert.DeserializeObject<JObject>(json, settings);
var decimalValues = obj.Descendants().OfType<JValue>().Where(v => v.Value is decimal).ToList();
foreach (var value in decimalValues)
{
value.Replace(new JRaw(((decimal)value.Value).ToString("0.00000E0" /*, System.Globalization.CultureInfo.InvariantCulture */))); // Is System.Globalization.CultureInfo.InvariantCulture available?
}
var newJson = obj.ToString(Formatting.Indented);
结果是
{
"x1": 1.55391E4,
"x2": 2.21732E5,
"x3": 1.11226E3,
"UpdatedDateTime": "2023-01-17T20:45:51.959+08:00"
}
在这里演示小提琴#1。
指出:
您的代码在Azure APIM策略表达式中。在这样的表达式中只允许非常有限的一组类型,正如. net框架中策略表达式中允许的类型所记录的那样。值得注意的是,以下是不可用的:
Newtonsoft.Json.JsonConverter
.Newtonsoft.Json.JsonTextReader
和JsonTextWriter
.System.Text.Json
(all).
缺乏任何创建自定义转换器的能力,这就是我建议使用
JRaw
的原因。你不能在Json.NET中保留原始的十进制格式。当
JsonTextReader
遇到浮点JSON数时,将其解析为decimal
或double
,并且丢弃原始JSON字符序列. 因此,仅保留值(decimal
的情况下为位数)。Utf8JsonReader
from System.Text。另一方面,Json保留了底层的Json字符序列。这个字符序列被传递给JsonElement
和JsonNode
,它们也保留了原始字符序列,并呈现它的只读(或可编辑)视图。因此,如果Azure APIM策略表达式被增强以允许System.Text.Json,您将能够更容易地保留原始的JSON十进制格式。在这里演示小提琴#2。
如果你想留下所有的日期&时间字符串值不变,而不是
DateParseHandling.DateTimeOffset
,您可以使用DateParseHandling.None
来完全禁用日期时间识别。