0

我有以下字典:

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));

这只影响“_v”值的序列化方式,例如:

{ "decimal" : { "_t" : "System.Decimal", "_v" : 3.503 }, "int" : 45 } 

预期结果:

{ "decimal" : 3.503, "int" : 45 } 

请指教

4

2 回答 2

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());

这仍然不适用于哈希表。哈希表的可能解决方法:

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));
于 2016-04-07T18:29:37.787 回答
0

bson 中 .Net 类型的原因是字典中缺少类型。Bson 序列化程序试图获得足够的状态来恢复字典中项目的原始对象。从上下文(字典)来看,它们属于“对象”类型,因此在反序列化时插入 .Net 类型以了解足够多的信息。

以下解决方案回答了您的问题,但丢失了反序列化的类型信息

解决方案1:将字典类型更改为<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 }

解决方案 2:将字典类型更改为<string, double>

var dict = new Dictionary<string, double> {
  { "decimal", (double)3.503m },
  { "int", 45 }
};
var serializedString = dict.ToJson();

结果是预期的结果:{ "decimal" : 3.503, "int" : 45 }

解决方案 3:使用自定义序列化程序

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;
  }
}
于 2016-04-07T12:57:09.910 回答