With mongo some operations will return a dynamic object, usually wrapped in an expando object. To deserialize the expando object in the target class is quite simple, I actually looked in the source code to see how the driver performs this operation.
If you look at the test involving the dynamic type here (https://github.com/mongodb/mongo-csharp-driver/blob/b473de06f9bf3587b3a00f52ba2678d9aed71d74/tests/MongoDB.Bson.Tests/Serialization/Serializers/ObjectSerializerTests.cs) you will see the process.
Let’s assume we made a query that returned an object which needs to be deserialized to the following model:
public class Courses { public string Name { get; set; } } public class Person { [BsonId(IdGenerator = typeof(GuidGenerator))] [BsonIgnoreIfDefault] public Guid UniqueId { get; set; } [BsonElement("LastName")] public string Name { get; set; } public string FirstName { get; set; } public List Scores { get; set; } public Courses Courses { get; set; } }
Our solve method takes 2 lines of code from the github source:
public static TProjection Solve(ExpandoObject keyValuePairs) where TProjection : class { var bson = keyValuePairs.ToBson(configurator: b => b.IsDynamicType = t => t == typeof(ExpandoObject)); var rehydrated = BsonSerializer.Deserialize(bson, b => b.DynamicDocumentSerializer = BsonSerializer.LookupSerializer()); return rehydrated; }
And for our test we will manually create an expando object
IDictionary<string, object> personExpando = new ExpandoObject(); personExpando.Add("LastName", "Rami"); personExpando.Add("FirstName", "John"); personExpando.Add("Scores", new List { 1, 2, 3 }); IDictionary<string, object> courses = new ExpandoObject(); courses.Add("Name", "Math"); personExpando.Add("Courses", courses); personExpando.Add("_id", "b5c5cf38-e0c9-4b93-b8e5-b9c7f6c1839b");