-
Type: Bug
-
Resolution: Done
-
Priority: Minor - P4
-
None
-
Affects Version/s: 2.0.1
-
Component/s: Serialization
-
None
Types:
class ContainerV1 { public string Id { get; set; } public bool A { get; set; } } class ContainerV2 { public string Id { get; set; } public bool A { get; set; } public SubItem[] Blah { get; set; } }
Code:
var mongo = new MongoClient("mongodb://localhost"); // start from scratch mongo.DropDatabaseAsync("foo").GetAwaiter().GetResult(); var test = mongo.GetDatabase("foo"); // insert ContainerV1 record (without array member) var coll1 = test.GetCollection<ContainerV1>("bar"); var item = new ContainerV1 { Id = Guid.NewGuid().ToString("N"), A = true }; coll1.InsertOneAsync(item).GetAwaiter().GetResult(); // get from same collection after model changes. var coll2 = test.GetCollection<ContainerV2>("bar"); var results = coll2.AsQueryable().Where(i => i.A).Select(i => new { Blah = i.Blah }).ToArray();
The exception: "No matching creator found." (BsonSerializationException), from BsonClassMapSerializer.ChooseBestCreator.
The reason:
Here's the server command:
{ "aggregate" : "bar", "pipeline" : [{ "$match" : { "A" : true } }, { "$project" : { "Blah" : "$Blah", "_id" : 0 } }], "cursor" : { } }
The response:
{ "cursor" : { "id" : NumberLong(0), "ns" : "foo.bar", "firstBatch" : [{ }] }, "ok" : 1.0 }
Basically, the array part of the projection comes back as an empty document when it doesn't exist, as would be the case when the member is new. BsonClassMapSerializer.DeserializeClass() doesn't populate any values from it of course, and no missing values are populated because the array member is marked IsReadOnly.
In ChooseBestCreator, the MostArgumentsCreatorSelector() looks for an appropriate creator, but with no values it can't determine one.
I'm not 100% on what the bug is, but perhaps - looking at DeserializeClass() - MemberMap.IsReadOnly for the array property of the projection should not be null, or should not be checked for null when dealing with missing values?
(Marking as minor since I'm not sure if the deserialisation code should be expected to deal with whatever crazy cases might be thrown at it like this)
- depends on
-
CSHARP-2643 Automapped serializer for anonymous classes should use default values for missing elements when deserializing
- Closed