[CSHARP-3263] BsonSerializer fails to resolve custom serializer. StackOverflow exception when register derived serializers Created: 20/Nov/20 Updated: 27/Oct/23 Resolved: 12/Dec/20 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | Serialization |
| Affects Version/s: | 2.11.4 |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Eduard Muradov | Assignee: | James Kovacs |
| Resolution: | Gone away | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Description |
|
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):
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.
|
| Comments |
| Comment by Backlog - Core Eng Program Management Team [ 12/Dec/20 ] | |||||
|
There hasn't been any recent activity on this ticket, so we're resolving it. Thanks for reaching out! Please feel free to comment on this if you're able to provide more information. | |||||
| Comment by James Kovacs [ 27/Nov/20 ] | |||||
|
Hi, Eduard, Thank you for the update and additional details. Please let us know if you can reliably reproduce the stack overflow as we would like to investigate this further. We look forward to reviewing any further examples that you can provide. Sincerely, | |||||
| Comment by Eduard Muradov [ 27/Nov/20 ] | |||||
|
Hi James, thank you for looking into this. Adding a serializer for a nominal type was a first thing I attempted but I got an error saying that its missing serializer for a declared type (IDictionary). Then, I tried adding both of the serializer registrations, for IDictionary and Dictionary, and the program started silently crashing; when I tried to debug it, it looked like infinite loop trying to resolve serializer ending up with SO exception at the end. I will take a look at it in more detail over the weekend and will provide a better examples for this issue (the object I was getting this errors from is much more complicated than I showed above). Once again, thank you for looking into this.
| |||||
| Comment by James Kovacs [ 24/Nov/20 ] | |||||
|
Hi, Eduard, Thank you for providing the repro. We understand that you are trying to serialize a child dictionary as a document using integer keys and it is failing with the following exception: MongoDB.Bson.BsonSerializationException: When using DictionaryRepresentation.Document key values must serialize as strings When the driver attempts to serialize the IDictionary<int, Node> property, it finds the registered serializer (with the new Int32Serializer(BsonType.String) for the key. Because the nominal type of the property (IDictionary<int, Node>) does not match the concrete type of the class that you are serializing, we perform a lookup for a Dictionary<int, Node> serializer, don't find one, and create a default one using new Int32Serializer(BsonType.Int32) for the key. This is why the driver fails with the above exception - because of the implicitly created concrete serializer. In order to serialize and deserialize the dictionary, we need to know the concrete class - in this case Dictionary<int, Node>. So rather than registering the interface with the BsonSerializer register the concrete class instead.
This will allow the driver to serialize the underlying concrete class Dictionary<int, Node> correctly. If you use other concrete classes such as SortedDictionary<K,V>, you would need to register those too. For more complex scenario, you can register a custom serializer against the interface, which will give you complete control over the serialization/deserialization of any type implementing that interface. Please let us know if you have any additional questions and whether registering serializers for the concrete type(s) resolves your issue. ASIDE: We were unable to reproduce the stack overflow exception that you reported when registering both the interface and concrete types. If you are still encountering this issue, please provide a repro that throws a StackOverflowException so that we can investigate further. Sincerely, | |||||
| Comment by Eduard Muradov [ 20/Nov/20 ] | |||||
|
Thank you for a quick response! | |||||
| Comment by Jeffrey Yemin [ 20/Nov/20 ] | |||||
|
Thanks for letting us know that you're experiencing this problem with serialization. We'll have a look soon and get back to you with the results of our initial investigation. |