我有以下字典:
var dict = new Dictionary<string, object> {
{ "decimal", 3.503m },
{ "int", 45 }
};
var serializedString = dict.ToJson();
默认情况下序列化为:
{ "decimal" : { "_t" : "System.Decimal", "_v" : "3.503" }, "int" : 45 }
如果我将DecimalSerializer覆盖为:
BsonSerializer.RegisterSerializer<decimal>(new DecimalSerializer().WithRepresentation(BsonType.Double));
这只影响&#34; _v&#34;值是序列化的,例如:
{ "decimal" : { "_t" : "System.Decimal", "_v" : 3.503 }, "int" : 45 }
预期结果:
{ "decimal" : 3.503, "int" : 45 }
请告知
答案 0 :(得分:0)
bson中.Net类型的原因是字典中缺少类型。 Bson序列化程序试图获得足够的状态来恢复字典中项目的原始对象。从上下文(字典)中它们是“对象”类型,因此插入.Net类型以便在反序列化时足够了解。
以下解决方案可以回答您的问题,但会丢失反序列化的类型信息。
<string, decimal>
var dict = new Dictionary<string, decimal> {
{ "decimal", 3.503m },
{ "int", 45 }
};
var serializedString = dict.ToJson();
结果:{ "decimal" : "3.503", "int" : "45" }
通过覆盖十进制序列化程序,可以得到预期的结果。
{ "decimal" : 3.503, "int" : 45 }
<string, double>
var dict = new Dictionary<string, double> {
{ "decimal", (double)3.503m },
{ "int", 45 }
};
var serializedString = dict.ToJson();
预期结果的结果:{ "decimal" : 3.503, "int" : 45 }
public class MyDictionarySerializer : SerializerBase<Dictionary<string, object>>
{
public override void Serialize(MongoDB.Bson.Serialization.BsonSerializationContext context, MongoDB.Bson.Serialization.BsonSerializationArgs args, Dictionary<string, object> dictionary)
{
context.Writer.WriteStartArray();
foreach (var item in dictionary)
{
context.Writer.WriteStartDocument();
context.Writer.WriteString(item.Key);
// TODO your converstions from object to double
var value = (double)item.Value;
context.Writer.WriteDouble(value);
context.Writer.WriteEndDocument();
}
context.Writer.WriteEndArray();
}
public override Dictionary<string, object> Deserialize(MongoDB.Bson.Serialization.BsonDeserializationContext context, MongoDB.Bson.Serialization.BsonDeserializationArgs args)
{
context.Reader.ReadStartArray();
var result = new Dictionary<string, object>();
while (true)
{
try
{
//this catch block only need to identify the end of the Array
context.Reader.ReadStartDocument();
}
catch (Exception exp)
{
context.Reader.ReadEndArray();
break;
}
var key = context.Reader.ReadString();
double value = context.Reader.ReadDouble();
result.Add(key, value);
context.Reader.ReadEndDocument();
}
return result;
}
}
答案 1 :(得分:0)
作为另一种选择,可以覆盖对象序列化器
public class DecimalsOverridingObjectSerializer : ObjectSerializer
{
public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value) {
if (value != null && value is decimal) {
base.Serialize(context, args, Convert.ToDouble(value));
} else {
base.Serialize(context, args, value);
}
}
}
BsonSerializer.RegisterSerializer(typeof(object), new DecimalsOverridingObjectSerializer());
仍然不适用于Hashtables。 Hashtables的可能解决方法:
public class DecimalsOverridingDictionarySerializer<TDictionary>:
DictionaryInterfaceImplementerSerializer<TDictionary>
where TDictionary : class, IDictionary, new()
{
public DecimalsOverridingDictionarySerializer(DictionaryRepresentation dictionaryRepresentation)
: base(dictionaryRepresentation, new DecimalsOverridingObjectSerializer(), new DecimalsOverridingObjectSerializer())
{ }
}
BsonSerializer.RegisterSerializer(typeof(Hashtable), new DecimalsOverridingDictionarySerializer<Hashtable>(DictionaryRepresentation.Document));