Search code examples
c#mongodbmongodb-.net-driver

Dictionary<string, object> serialization


My data class contains Dictionary field for some highly diverse data.

internal class Program
{
    public class DTO
    {
        public string Name { get; set; }
        public Dictionary<string, object> Data { get; set; }
    }

    static void Main(string[] args)
    {
        var dictSerializer = new DictionaryInterfaceImplementerSerializer<Dictionary<string, object>>(DictionaryRepresentation.Document);
        BsonClassMap.RegisterClassMap<DTO>(cm => cm.MapMember(dto => dto.Data).SetSerializer(dictSerializer));

        var instance = new DTO
        {
            Name = "test",
            Data = new Dictionary<string, object>
                {
                    {"str", "thestring"},
                    {"byte", (byte)42},
                    {"bytearray", new byte[]{ 0x1, 0x2, 0x3}}
                }
            };

        var col = new MongoClient("mongodb://localhost:27017").GetDatabase("test").GetCollection<DTO>("test");
        col.InsertOne(instance);
    }
}

And I got:

{ 
    "_id" : ObjectId("56a9eeeacdc5b3ea38c0a522"), 
    "Data" : {
        "str" : "thestring", 
        "byte" : {
            "_t" : "System.Byte", 
            "_v" : NumberInt(42)
        }, 
        "bytearray" : {
            "_t" : "System.Byte[]", 
            "_v" : BinData(0, "AQID")
        }
    }
}

As you see, "byte" and "bytearray" fields serialized with discriminators "_" and "_v". But I expect something like this:

{ 
    "_id" : ObjectId("56a9eeeacdc5b3ea38c0a522"), 
    "Data" : {
        "str" : "thestring", 
        "byte" : 42,
        "bytearray" : BinData(0, "AQID"))
    }
}

How can I achieve this?


Solution

  • If it is possible to use Newtonsoft for Serializing and Deserializing your object, Newtonsoft is the best solution for Serialization operations. Can you please try the code below ?

    using Newtonsoft.Json;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace DictionaryTest
    {
        class Program
        {
            public class DTO
            {
                public string Name { get; set; }
                public Dictionary<string, object> Data { get; set; }
            }
    
            static void Main(string[] args)
            {
                //var dictSerializer = new DictionaryInterfaceImplementerSerializer<Dictionary<string, object>>(DictionaryRepresentation.Document);
                //BsonClassMap.RegisterClassMap<DTO>(cm => cm.MapMember(dto => dto.Data).SetSerializer(dictSerializer));
    
                DTO instance = new DTO
                {
                    Name = "test",
                    Data = new Dictionary<string, object>
                    {
                        {"str", "thestring"},
                        {"byte", (byte)42},
                        {"bytearray", new byte[]{ 0x1, 0x2, 0x3}}
                    }
                };
    
                string serializedOne = JsonConvert.SerializeObject(instance);
    
                var col = new MongoClient("mongodb://localhost:27017").GetDatabase("test").GetCollection<DTO>("test");
                col.InsertOne(serializedOne);
                Console.WriteLine(serializedOne);
                Console.ReadKey();
            }
        }
    }
    

    PS: I'm not a MongoDB expert and I remember that I was succesfully done an operation in past something like that.

    Newtonsoft.JSON Official Page: http://www.newtonsoft.com/json

    Newtonsoft.JSON NuGet Page: https://www.nuget.org/packages/Newtonsoft.Json/

    Hope this helps you