RavenDB 5.4 序列化和反序列化 Decimal 格式

问题描述 投票:0回答:3

我要求从 RavenDB 检索的十进制值具有与存储时相同的格式。 示例属性值 33

数据库中存储的序列化 json 存储的值恰好为 33,这与预期一致。但反序列化时,我在 Decimal 属性中得到值 33.0。

我尝试使用自定义 JsonConverter 只是为了检查反序列化时发生的情况

public class DecimalFormatConverter : JsonConverter { public override bool CanConvert(Type objectType) { return objectType == typeof(decimal); } public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { return Convert.ToDecimal(reader.Value); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteValue((decimal)value); } }

在ReadJson中,检查
reader.Value

时,它是33.0(应该是33)。我无法在这里实现舍入或自定义格式,因为如果该值存储为 33.0 或 33.00,则加载时必须保持完全相同的格式。 我已经定了

serializer.FloatParseHandling = Newtonsoft.Json.FloatParseHandling.Decimal;

尽管这在本例中可能不相关。

json.net deserialization ravendb
3个回答
4
投票
https://github.com/JamesNK/Newtonsoft.Json/issues/1726

这有几个含义,但基本上意味着您需要使用正确的格式将数据写入输出格式。

您需要使用

FloatParseHandling = FloatParseHandling.Decimal

和以下转换器:

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
    writer.WriteRawValue(value.ToString());
}

请注意,我们将小数值
作为字符串

写入输出,不使用引号。 解析时,FloatParseHandling.Decimal会将其读取为十进制,其余就可以了。

请注意,服务器端操作将在内部使用双精度数。

另请参阅:

https://ravendb.net/docs/article-page/5.4/csharp/server/kb/numbers-in-ravendb

https://ravendb.net/docs/article-page/5.4/csharp/client-api/configuration/serialization#numbers-deserialization


0
投票

if (reader.TokenType == JsonToken.String) { string value = (string)reader.Value; if (decimal.TryParse(value, out decimal result)) return result; } else if (reader.TokenType == JsonToken.Float) { // Preserve the exact format return decimal.Parse(reader.Value.ToString(), CultureInfo.InvariantCulture); }



0
投票

如果代码以不同的文化小数格式运行(例如小数分隔符 . 或 ,取决于文化),它会弄乱小数。

到目前为止我找到的最好的解决方案是:

public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer) { if (reader.Value == null) return null; return Convert.ToDecimal(reader.Value, CultureInfo.InvariantCulture); } public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) { writer.WriteValue(Convert.ToDecimal(value).ToString(CultureInfo.InvariantCulture)); }

© www.soinside.com 2019 - 2024. All rights reserved.