[CSHARP-75] Deserialization discriminators are too lazy Created: 19/Oct/10 Updated: 19/Oct/16 Resolved: 20/Oct/10 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | None |
| Affects Version/s: | None |
| Fix Version/s: | None |
| Type: | Bug | Priority: | Critical - P2 |
| Reporter: | Justin Dearing | Assignee: | Robert Stam |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Description |
|
Long story short, this works: .", ret.ToJson()); Take away the ToJson() call it breaks because BsonClassMap.AutoMap() does not get called which causes BsonClassMap.LookupActualType() to fail. I am not sure how to fix. Let me know if you need a better description and I can provide one. |
| Comments |
| Comment by Robert Stam [ 20/Oct/10 ] |
|
Or maybe even: BsonClassMap.LookupClassMap(typeof(Book)); If you're willing to make sure you only call them once you could use: BsonClassMap.RegisterClassMap<Book>(); RegisterClassMap throws an exception if you try to register the same class more than once. Or just use the [BsonKnownType] attribute! Good catch. |
| Comment by Justin Dearing [ 20/Oct/10 ] |
|
A small amendment to Robert's comment. The correct syntax is: BsonClassMap.LookupClassMap<Book>(); |
| Comment by Robert Stam [ 20/Oct/10 ] |
|
This is the result of an attempt to deserialize an instance of a class that has not yet been mapped (auto or otherwise). The reason calling ToJson first worked is because as a side effect of calling ToJson the class was automapped. This is a common case when you are deserializing the base class of an inheritance hierarchy. The different .NET serializers have various ways of telling the serializer about the "known types" that will be deserialized. In our case, I've added a BsonKnownTypeAttribute for this purpose. Here's a sample family of classes: [BsonKnownType(typeof(Book))] public class Book : Product { [BsonElement("title")] public string Title { get; set; } } public class Magazine : Product { } public class PackingList { public IList<Product> Products { get; set; } } If you don't want to or can't annotate your classes with these attributes another way to make these classes "known" to the serializer is to call: BsonSerializer.LookupClassMap<Book>(); We are ignoring the return values. We only care about the side effect that the class is automapped if necessary (i.e, "known" to the serializer). |
| Comment by Justin Dearing [ 19/Oct/10 ] |
|
No that was a bad bad search and replace to "sanatize" my code Foo ret = new Foo(); .", ret.ToJson()); |
| Comment by Robert Stam [ 19/Oct/10 ] |
|
Is Event supposed to be a subclass of Foo? |