[CSHARP-675] Allow overriding of default serializers for built-in types Created: 06/Feb/13 Updated: 20/Mar/14 Resolved: 01/Mar/13 |
|
| Status: | Closed |
| Project: | C# Driver |
| Component/s: | Feature Request |
| Affects Version/s: | 1.7 |
| Fix Version/s: | None |
| Type: | New Feature | Priority: | Major - P3 |
| Reporter: | Daniel Goldman | Assignee: | Robert Stam |
| Resolution: | Done | Votes: | 0 |
| Labels: | None | ||
| Remaining Estimate: | Not Specified | ||
| Time Spent: | Not Specified | ||
| Original Estimate: | Not Specified | ||
| Attachments: |
|
| Description |
|
In the last version I was using (1.4), I was able to register a serializer that could assign any value to a field of type Object by calling the appropriate deserializer based on the BSON type and then assigning the result to the field. For example, given the following class definition: public class Stuff public object TheStuff { get; set; } } I could persist anything as TheStuff and my custom serializer would deserialize and assign the value appropriately. However, it doesn't seem possible to override the default serializers in the latest version, try though I might to find such a mechanism in the documentation and the source code. In the LookupSerializer method, the method returns as soon as it has found a mapped serializer, and as far as I can tell, the default serializers are getting registered before I have an opportunity to register my own. Registering a custom provider doesn't help either, as the driver only does a custom provider look-up if it hasn't found a serializer in the default dictionary. |
| Comments |
| Comment by Robert Stam [ 22/Feb/13 ] | |||||
|
I'm planning to close this JIRA ticket with a status of "works as designed". Let me know if you have any further questions or reasons you think the ticket should remain open. | |||||
| Comment by Robert Stam [ 11/Feb/13 ] | |||||
|
You need to be careful when calling Update that the values you are replacing during the Update are correctly serialized (otherwise Deserialize will fail as you are experiencing). The easiest way to make sure that all the values involved in Update are correctly serialized is to use the type safe version of Update. See the attached TestDeserializedNestedStuff2 program, the important part of which is this code:
Note that I also commented out the first part of the test where you aren't using your Stuff class. You probably don't want to be mixing BsonDocument style processing with POCO processing. Pick one or the other. I think everything is working as designed, but I will leave the JIRA ticket open a bit longer so that we can discuss further as needed. | |||||
| Comment by Daniel Goldman [ 10/Feb/13 ] | |||||
|
Apologies, this is a very poor bug report. The specific problem I'm having is that, when deserializing a nested document in a structured class that was put in place by an update, the deserialization throws an exception (please see attached test case). In version 1.4, I was able to register a serializer that handled instances of nominal type "object" using "BsonSerializer.RegisterSerializer(typeof(object), new MyObjectSerializer())." I used MyObjectSerializer principally to coerce into arrays of type object[] when the nominal type was an object and the BsonType was BsonArray, as this case didn't seem to be handled by the default serializer (I otherwise deferred to the default serializer). In addition to the problem described above, and more in the spirit of the initial report, it might also be valuable to be able to hook into the serialization/deserialization process for the existing serializers, or in extreme cases, to provide a custom version of some of the existing serializers. I appreciate your comment about the implications of overriding the object serializer and will definitely try to avoid doing so. However, if for some extreme reason my application needed to override the object serializer, it didn't appear to be possible to do so; I may be missing something, but if I were to register a custom serialization provider that yielded up a custom serializer for the object type, my serializer would never be retrieved because the default object serializer would always be returned first. | |||||
| Comment by Daniel Goldman [ 10/Feb/13 ] | |||||
|
Test case illustrating the problem described. | |||||
| Comment by Robert Stam [ 07/Feb/13 ] | |||||
|
What is preventing you from calling RegisterSerializer (in BsonSerializer) just like you could in previous versions of the driver? I don't think anything has changed that would affect how you would register a serializer. Can you attach a sample program illustrating what it is that is not working for you? I hope you weren't overriding the standard serializer for typeof(object)... that seems dangerous, as serialization of nominal type object occur in many other places besides your class Stuff. What you could do is set a custom serializer for JUST your TheStuff property. See SetSerializer in BsonMemberMap. |