[CSHARP-961] StackoverflowException deserializing Dictionary<string, Interface> Created: 25/Apr/14 Updated: 02/Apr/15 Resolved: 29/Apr/14 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | Serialization |
| Affects Version/s: | 1.8.3, 1.9 |
| Fix Version/s: | 1.9.1 |
| Type: | Bug | Priority: | Major - P3 |
| Reporter: | Andrew Martinez | Assignee: | Robert Stam |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Description |
|
Experienced When deserializing a class that has a property defines as Dictionary<string, Interface> a StackoverFlow exception will be thrown in mscorlib.dll. If the property is changed to Dictionary<string, Concrete> the issue does not occur. Expected Interface deserialization on Dictionary properties where the value is an interface type should work. Reproduction Console Main
Interfaces
Concretes
Example Document
|
| Comments |
| Comment by Andrew Martinez [ 25/Apr/14 ] | ||||||||
|
This exact example was created to represent my actual issue. I'm issuing a mapReduce query that returns a data structure that is created in the finalize execution. I am essentially creating a object mapping of types to counts. This object mapping does not actually exist on its own in any collection nor is it initially persisted from c#; it is just a product of the mapReduce. I was using the response object to mapReduceResponse.GetInlineResultsAs<Concrete>, where the concrete was very similar to the Parent concrete in my example (having a Dictionary<string, Interface> property). If I understand the situation, my only option is to deserialize this myself; correct? Or is there another path that I can take? Edit: The more I think about this the more I realize that my mapReduce output is pretty concrete. There can really never be other representations without altering the mapReduce logic which would in turn immediately require changes to the types. The only time I would need it is if I was persisting the data which would be covered by the discriminator (_t) attribute. Anyways, at least I found that StackoverFlow exception. | ||||||||
| Comment by Robert Stam [ 25/Apr/14 ] | ||||||||
|
We have resolved the StackOverflowException that occurred when _t was missing from the Child documents. Instead, there will be a FileFormatException with the following message: Unable to determine actual type of object to deserialize. NominalType is the interface MongoDB.BsonUnitTests.Jira.CSharp961Tests+IChild. (The actual interface name would vary slightly for you...). But we are still unable to deserialize Child documents when the _t is missing. That's a somewhat bigger problem, namely "how would we determine which actual concrete class to use for an arbitrary interface if there was no _t to tell us that?". | ||||||||
| Comment by Githook User [ 25/Apr/14 ] | ||||||||
|
Author: {u'name': u'rstam', u'email': u'robert@10gen.com'}Message: | ||||||||
| Comment by Robert Stam [ 25/Apr/14 ] | ||||||||
|
If I save a Parent document to the database and read it back I don't get a StackOverflowException. But if I try to read back your sample document I do. The document that my test saved to the database differs slightly from your sample document, in that the Dictionary values have an _t discriminator value in them. The discriminator is used during deserialization to determine which concrete class to instantiate (you can't instantiate interfaces, only concrete classes can be instantiated). Here's what the Parent document looks like when I save a Parent to the database:
When the _t is missing the driver ends up in a recursive code path that eventually results in a StackOverflowException. What should happen is an error message saying that the _t discriminator is missing and that the driver is unable to determine which concrete class to use. | ||||||||
| Comment by Robert Stam [ 25/Apr/14 ] | ||||||||
|
Thanks for reporting this. I will reproduce it and figure out what's happening. | ||||||||
| Comment by Andrew Martinez [ 25/Apr/14 ] | ||||||||
|
Expected output:
|