0

I am using MongoDB with the 1.10.0 driver. I have an entity with a dynamic member. This entity is contained within a collection of itself on a parent, which is ultimately serialized.

public class MyEntity
{
    public List<MySubEntity> Items { get; set; }
}

public class MySubEntity
{
    public dynamic Value { get; set; }

    public MySubEntity()
    {
        Value = new ValueString();
    }
}

public class ValueString
{
    public string Value { get; set; }
}

The serialization of this object works fine, and I can see there is an additional property _t serialized with the MySubEntity instance with a value of ValueString.

The very first time I attempt to retrieve this from Mongo, it deserializes fine and all data comes out. However, and future attempts fail.

{"An error occurred while deserializing the Answer property of class MySubEntity: Unknown discriminator value 'ValueString'."}

at MongoDB.Bson.Serialization.BsonClassMapSerializer.DeserializeMemberValue(BsonReader bsonReader, BsonMemberMap memberMap)
at MongoDB.Bson.Serialization.BsonClassMapSerializer.Deserialize(BsonReader bsonReader, Type nominalType, Type actualType, IBsonSerializationOptions options)
at MongoDB.Bson.Serialization.BsonClassMapSerializer.Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
at MongoDB.Driver.Internal.MongoReplyMessage`1.ReadBodyFrom(BsonBuffer buffer)
at MongoDB.Driver.Internal.MongoReplyMessage`1.ReadFrom(BsonBuffer buffer)
at MongoDB.Driver.Internal.MongoConnection.ReceiveMessage[TDocument](BsonBinaryReaderSettings readerSettings, IBsonSerializer serializer, IBsonSerializationOptions serializationOptions)
at MongoDB.Driver.Operations.QueryOperation`1.GetFirstBatch(IConnectionProvider connectionProvider)
at MongoDB.Driver.Operations.QueryOperation`1.Execute(IConnectionProvider connectionProvider)
at MongoDB.Driver.MongoCursor`1.GetEnumerator()
at MongoDB.Driver.Linq.IdentityProjector`1.GetEnumerator()
at System.Linq.Enumerable.FirstOrDefault[TSource](IEnumerable`1 source)
at MongoDB.Driver.Linq.SelectQuery.<TranslateFirstOrSingle>b__b(IEnumerable source)
at MongoDB.Driver.Linq.SelectQuery.Execute()
at MongoDB.Driver.Linq.MongoQueryProvider.Execute(Expression expression)
at MongoDB.Driver.Linq.MongoQueryProvider.Execute[TResult](Expression expression)
at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate)

Is there something I might be missing on how to do this? I cannot add any attributes to any of the classes, so any changes would need to be done from a runtime configuration.

To access the entity, I'm using MongoCollection<T>.AsQueryable() and filtering from there.

EDIT - The change from "Works" to "Not working with above error" seems to occur between initializations of the Mongo connection. I am running in an ASP.NET Web Api. So the initial submission is OK, and subsequent refreshes back to the database work. It's not until I re-debug the web app does the connection fail.

1 Answer 1

1

You have to specify how to map the types defined in your documents.

Here some sample. In my project any serialized class as an Interface IDataObject (root object) or IDatamapped. At application startup I ensure that all my classes are registered.

There is more to say about it you should check the mongo documentation :=)

Like :

  1. [BsonDiscriminator(RootClass = true)]
  2. [BsonId( IdGenerator = typeof(ObjectIdGenerator))]
  3. [BsonExtraElements]

and how to create custom maps.

     public static void DefaultMappers(Assembly asm) 
     {
          foreach (Type t in asm.GetTypes())
          {
              if (t.GetInterface(typeof (IDataObject).Name) != null)
              {
                  BsonClassMap.LookupClassMap(t);
                  continue;
              }

              if (t.GetInterface(typeof(IDataMapped).Name) != null)
              {
                  BsonClassMap.LookupClassMap(t);
                  continue;
              }
          }
     }
Sign up to request clarification or add additional context in comments.

3 Comments

I've had a hard time understanding when and what needs mapping. Basically, all the basic types (and their children) that are set to be used in the collections in Mongo are automatically mapped. The time you need to explicitly map are when you are using dynamics, interface backed properties, base types, etc. Basically map any type that isn't explicitly declared as the type in the collection.
Sorry for demanding for help but is it possible to deserialize dynamic and object to a generic BsonDocument? stackoverflow.com/questions/36202460/…
MongoDB.Bson.BsonExtensionMethods Accepts ToJson() or ToBsonDocument, ToBson() for any object

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.