Search code examples
c#mongodbserializationbson

Deserialize Mongodb string to object


I have an object as a property that i've created a custom serializer for. All it does is call ToString because i want to represent the data as a string in my collection.

cm.MapMember(c => c.myObjectProperty).SetSerializer(new ObjectToStringSerializer() );

The above is called only once and works well when saving the data. I can see the parent object with the string value as expected.

Here is the basic serializer:

public class ObjectToStringSerializer : IBsonSerializer {


        #region IBsonSerializer Members

        public object Deserialize(MongoDB.Bson.IO.BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
        {
            if (bsonReader.State == MongoDB.Bson.IO.BsonReaderState.Type && bsonReader.CurrentBsonType != MongoDB.Bson.BsonType.Null)
                return Activator.CreateInstance(nominalType, new object[] { bsonReader.ReadString() });
            return null;
        }

        public object Deserialize(MongoDB.Bson.IO.BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
        {

            if( bsonReader.State == MongoDB.Bson.IO.BsonReaderState.Type && bsonReader.CurrentBsonType != MongoDB.Bson.BsonType.Null)
                return Activator.CreateInstance(nominalType, new object[] { bsonReader.ReadString() });
            return null;
        }

        public IBsonSerializationOptions GetDefaultSerializationOptions()
        {
            throw new NotImplementedException();
        }

        public void Serialize(MongoDB.Bson.IO.BsonWriter bsonWriter, Type nominalType, object value, IBsonSerializationOptions options)
        {


            if (value != null)
            {
                bsonWriter.WriteString(value.ToString());
            }
            else
                bsonWriter.WriteNull();

        }

        #endregion
    }

When I try to get the parent object back from the collection an exception is thrown:

ReadBsonType can only be called when State is Type, not when State is Value.

And the stack trace doesn't look like it tries to call my custom serializer's deserialize method.

What am I missing in order for my deserialize method I expect to be called? I've tried adding a simple serializationprovider but I don't think thats right. I've also tried regestering the serializer.

BsonSerializer.RegisterSerializer(typeof(myObjectPropertyType), new ObjectToStringSerializer());

Solution

  • The problem was my conditions on the Deserialize members.

    if (bsonReader.State == MongoDB.Bson.IO.BsonReaderState.Type && bsonReader.CurrentBsonType != MongoDB.Bson.BsonType.Null)
    

    The call was never made to the creator. I've changed it to

    if (bsonReader.State == MongoDB.Bson.IO.BsonReaderState.Value && bsonReader.CurrentBsonType == MongoDB.Bson.BsonType.String)