-
Type:
Bug
-
Resolution: Gone away
-
Priority:
Major - P3
-
None
-
Affects Version/s: 2.11.4
-
Component/s: Serialization
-
None
-
None
-
None
-
None
-
None
-
None
-
None
-
None
It looks like BsonSerializer fails to resolve proper serializer for a member when declared member type doesn't match actual initialized type.
Observed code flow (might not be exact):
- BsonMemberMap looks up serializer and calls .Serialize() on found serializer (via extension method I believe).
- Matched serializer of type ClassSerializerBase<T> calls Serialize() method on base class.
Serialize() method looks up serializer on actual runtime type (e.g. value.GetType()) which fails to find serializer for a concrete type.
If you register concrete type serializer as well, driver fails with StackOverflow exception because of infinite serializer lookup loop.
Please take a look at minimal repro below.
class Program { public class Root { // Initialized type doesn't match declared type!!! public IDictionary<int, Node> Nodes { get; set; } = new Dictionary<int, Node>(); } public class Node { public string Name { get; set; } } static void Main(string[] args) { BsonSerializer.RegisterSerializer(typeof(IDictionary<int, Node>), GetInt32Serializer<Node>()); var root = new Root(); root.Nodes.Add(0, new Node { Name = "Test" }); using (var stringWriter = new StringWriter()) { using (var writer = new JsonWriter(stringWriter)) { BsonSerializer.Serialize(writer, root); Console.WriteLine("Valid Root: {0}", stringWriter.ToString()); } } Console.ReadKey(); } private static IBsonSerializer GetInt32Serializer<TValue>() { return new DictionaryInterfaceImplementerSerializer<IDictionary<int, TValue>, int, TValue>( DictionaryRepresentation.Document, new Int32Serializer(BsonType.String), BsonSerializer.SerializerRegistry.GetSerializer<TValue>()); } }