[英]How to show the decimal value as it is when Deserializing using JSON.NET in Azure APIM?
I'm using Azure APIM policy expression to aggregate multiple responses.我正在使用 Azure APIM 策略表达式来聚合多个响应。 I have some decimal values in the response.
我在响应中有一些小数值。 But while Deserializing, formatting was changed as shown in the output. I want to return as in the Input.
但是在反序列化时,格式已更改,如 output 所示。我想返回输入中的格式。
INPUT输入
{
"x1": 1.55391E4,
"x2": 2.2173244E5,
"x3": 1.11226E3,
"UpdatedDateTime": "2023-01-17T20:45:51.959+08:00"
}
OUTPUT OUTPUT
{
"x1": 15539.1,
"x2": 221732.44,
"x3": 1112.26,
"UpdatedDateTime": "2023-01-17T20:45:51.959+08:00"
}
EXPECTED预期的
{
"x1": 1.55391E4,
"x2": 2.2173244E5,
"x3": 1.11226E3,
"UpdatedDateTime": "2023-01-17T20:45:51.959+08:00"
}
In this sample, I have preserved the DateTimeZone with Offset.在此示例中,我保留了带偏移量的 DateTimeZone。 but I can't do the decimal fields (x1, x2, x3).
但我不能做小数字段(x1、x2、x3)。 I just wants to return as it is like input.
我只想返回,因为它就像输入一样。
Please note that I'm writing this inside a policy expression, so I can't create any C# extensions or helper methods.请注意,我在策略表达式中编写此内容,因此我无法创建任何 C# 扩展或辅助方法。
One way to force scientific notation for decimal
values in a JToken
hierarchy would be to replace decimal-valued JValue
tokens with an appropriately formatted JRaw
value:在
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);
Which results in结果是
{
"x1": 1.55391E4,
"x2": 2.21732E5,
"x3": 1.11226E3,
"UpdatedDateTime": "2023-01-17T20:45:51.959+08:00"
}
Demo fiddle #1 here .演示小提琴 #1在这里。
Notes:笔记:
You code is inside an Azure APIM policy expression.您的代码位于 Azure APIM 策略表达式中。 Only a very limited set of types are allowed in such an expression, as documented in .NET Framework types allowed in policy expressions .
此类表达式中只允许使用非常有限的类型集,如.NET Framework types allowed in policy expressions中所述。 Of note, the following are not available :
请注意,以下内容不可用:
Newtonsoft.Json.JsonConverter
. Newtonsoft.Json.JsonConverter
。Newtonsoft.Json.JsonTextReader
and JsonTextWriter
. Newtonsoft.Json.JsonTextReader
和JsonTextWriter
。System.Text.Json
(all). System.Text.Json
(全部)。 The lack of any ability to create a custom converter is why I suggested to use JRaw
.缺乏创建自定义转换器的能力是我建议使用
JRaw
的原因。
You can't preserve the original decimal formatting with Json.NET. When JsonTextReader
encounters a floating point JSON number, it parses it to decimal
or double
and discards the original JSON character sequence .您不能使用 Json.NET 保留原始的十进制格式。当
JsonTextReader
遇到浮点数 JSON 数字时,它会将其解析为decimal
或double
精度并丢弃原始的 JSON 字符序列。 Thus only the value (and number of digits in the case of decimal
) is retained.因此,仅保留值(以及
decimal
情况下的位数)。
Utf8JsonReader
from System.Text.Json, on the other hand, does retain the underlying JSON character sequence.另一方面,来自 System.Text.Json 的
Utf8JsonReader
确实保留了底层的 JSON 字符序列。 This character sequence is passed off to JsonElement
and JsonNode
which also retain the original character sequence and present read-only (or editable) views of it.此字符序列被传递给
JsonElement
和JsonNode
,它们也保留原始字符序列并呈现它的只读(或可编辑)视图。 So if Azure APIM policy expressions are ever enhanced to allow System.Text.Json you would be able to retain the original JSON decimal formatting much more easily.因此,如果 Azure APIM 策略表达式得到增强以允许 System.Text.Json,您将能够更轻松地保留原始的 JSON 十进制格式。
If you want to leave all date & time string values unchanged, instead of DateParseHandling.DateTimeOffset
, you could use DateParseHandling.None
to disable DateTime recognition entirely.如果您想保留所有日期和时间字符串值不变,而不是
DateParseHandling.DateTimeOffset
,您可以使用DateParseHandling.None
完全禁用 DateTime 识别。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.