使用MongoDB Bson序列化器序列化对象图

时间:2011-06-03 12:25:26

标签: serialization mongodb mongodb-.net-driver bson

我一直在使用MongoDB Bson序列化器,使用以下代码:

class Program
{
    public class myValue
    {
        public int Id = 0;
        public string Label = "";
    }

    public class myValueMap : Dictionary<string, myValue>
    {
    }

    public class myProdData
    {
        public myValueMap  Mapping { get; set; }

    }
    public class mySystemPosition
    {
        public string Text { get; set; }
        public myProdData ProdData { get; set; }

    }
    static void Main(string[] args)
    {
        BsonClassMap.RegisterClassMap<mySystemPosition>();
        BsonClassMap.RegisterClassMap<myProdData>();
        BsonClassMap.RegisterClassMap<myValueMap>();
        BsonClassMap.RegisterClassMap<myValue>();
        var o = new mySystemPosition()
                    {
                        ProdData = new myProdData()
                                       {
                                           Mapping = new myValueMap()
                                                        {
                                                            {"123", new myValue() {Id = 1, Label = "Item1"}},
                                                            {"345", new myValue() {Id = 2, Label = "Item2"}},
                                                        }
                                       }
                    };
        var bson = o.ToBson();

        var text = Encoding.ASCII.GetString(bson);
    }
}

但是我似乎无法获得myProdData.Mapping序列化....

我是否需要以特殊方式配置MongoDB Bson序列化程序才能使其正常工作?

3 个答案:

答案 0 :(得分:0)

如果您不需要自定义序列化(documentation),则无需使用BsonClassMap.RegisterClassMap。 根据默认规则,您的所有课程都将被取消。

此外,我更改了您的示例以使其工作(我已使用词典替换myValueMap类):

    public class myProdData
    {
        public  Dictionary<string, myValue> Mapping { get; set; }
    }

    static void Main(string[] args)
    {
        var o = new mySystemPosition()
        {
            ProdData = new myProdData()
            {
                Mapping = new Dictionary<string, myValue>()
                {
                    {"123", new myValue() {Id = 1, Label = "Item1"}},
                    {"345", new myValue() {Id = 2, Label = "Item2"}},
                }
            }
        };

        var json = o.ToJson();
        Console.WriteLine(json);
        Console.ReadKey();
    }

这是控制台输出(格式正确):

{
    "Text":null,
    "ProdData":{
        "Mapping":{
            "123":{
                "_id":1,
                "Label":"Item1"
            },
            "345":{
                "_id":2,
                "Label":"Item2"
            }
        }
    }
}

您可以使用ToJson()扩展方法测试序列号,以便查看所有正确的序列,然后在需要时使用ToBson()

答案 1 :(得分:0)

问题是myValueMap派生自Dictionary。这导致AutoMap方法无法处理的类。

我建议你直接使用字典,正如安德鲁在答复中所做的那样。

答案 2 :(得分:0)

很遗憾,myValueMap是一个我无法轻易改变的对象,但事实证明,创建自己的(de)序列化器非常容易....

    public class myValueMapSerializer : IBsonSerializer
    {
        public object Deserialize(Bson.IO.BsonReader bsonReader, System.Type nominalType, System.Type actualType, IBsonSerializationOptions options)
        {
            if (nominalType != typeof(myValueMap)) throw new ArgumentException("Cannot serialize anything but myValueMap");
            var res = new myValueMap();
            var ser = new DictionarySerializer<string, myValue>();
            var dic = (Dictionary<string, myValue>)ser.Deserialize(bsonReader, typeof(Dictionary<string, myValue>), options);

            foreach (var item in dic)
            {
                res.Add(item.Key, item.Value);
            }
            return res;
        }

        public object Deserialize(Bson.IO.BsonReader bsonReader, System.Type nominalType, IBsonSerializationOptions options)
        {
            throw new Exception("Not implemented");
        }

        public bool GetDocumentId(object document, out object id, out IIdGenerator idGenerator)
        {
            id = null;
            idGenerator = null;
            return false;
        }

        public void Serialize(Bson.IO.BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
        {
            if (nominalType != typeof(myValueMap)) throw new ArgumentException("Cannot serialize anything but myValueMap");

            var ser = new DictionarySerializer<string, myValue>();
            ser.Serialize(bsonWriter, typeof(DictionarySerializer<string, myValue>), value, options);
        }

        public void SetDocumentId(object document, object id)
        {
            return;
        }
    }