Search code examples
mongodbmongodb-.net-driver

Custom deserialization


I have collection with thousands of documents, in document there's field named Rate, problem is currently its type is string, so when it's not available, the old developer set it to "N/A". For now I want to change the type of this field to numeric in C# (set it to 0 when n/a), but if I do so I can't load the past data. Can we customize the deserialization so it will convert N/A to 0?


Solution

  • You need to create an IBsonSerializer or SerializerBase<> and attach it to the property you wish to serialize using the BsonSerializerAttribute. Something like the following:

    public class BsonStringNumericSerializer : SerializerBase<double>
    {
        public override double Deserialize(BsonDeserializationContext context, BsonDeserializationArgs args)
        {
            var type = context.Reader.GetCurrentBsonType();
            if (type == BsonType.String)
            {
                var s = context.Reader.ReadString();
                if (s.Equals("N/A", StringComparison.InvariantCultureIgnoreCase))
                {
                    return 0.0;
                }
                else
                {
                    return double.Parse(s);
                }
            }
            else if (type == BsonType.Double)
            {
                return context.Reader.ReadDouble();
            }
            // Add any other types you need to handle
            else
            {
                return 0.0;
            }
        }
    }
    
    public class YourClass
    {
        [BsonSerializer(typeof(BsonStringNumericSerializer))]
        public double YourDouble { get; set; }
    }
    

    If you don't want to use attributes you can create an IBsonSerializationProvider and register it using BsonSerializer.RegisterSerializationProvider.

    Full documentation of MongoDB C# Bson serialization can be found here