Deserializing Nested Concrete Types with Custom Converter

41 views
Skip to first unread message

Russ McClelland

unread,
Jun 19, 2017, 12:38:03 PM6/19/17
to RavenDB - 2nd generation document database
I have a class (A) with a list of abstract types (AbstractB with subclasses C, D, E, etc). I have set up a custom converter so that when it is reading the list of AbstractB, if it reads a D, it does a custom look-up to handle object creation.  The problem is that the the converter only sees "string" as the .NET type coming into CanConvert() after a certain point. I have customized the converter using:

{
   serializer.TypeNameHandling = TypeNameHandling.Auto;
   serializer.Converters.Add( new CustomConverter( typeof( asmName.D ) ) );
}

Sample document in RavenDB:
{
    "elements": [
        {
            "$type": "asmName.C, asmName",
            "Value": null,
            "Name": "Test"
        },
        {
            "$type": "asmName.C, asmName",
            "Value": 2,
            "Name": "Test2"
        },
        {
            "$type": "asmName.D, asmName",
            "Name": "X"
        }
...

The first node comes through correctly as type "A". 
The next node ("elements") comes through correctly as "List<AbstractB>". 
The next node comes through correctly as "AbstractB"

Now the serializer gets to the 3 elements. Each one comes through as "System.String" *after* it already invoked the ctor for the correct type (either C or D).

1. Shouldn't the converter get a chance to handle the stream *before* the default ctors are invoked?
2. Any ideas as to why the elements come to the converter as "System.String" instead of "asmName.C" or "asmName.D"?
3. Is there a better mechanism for handling custom object creation when deserializing documents from Raven?


Oren Eini (Ayende Rahien)

unread,
Jun 20, 2017, 1:06:54 AM6/20/17
to ravendb
Why do you _need_ a custom converter here? This should just work. 
The likely issue is in your converter, but the json you showed should be properly deserialized without any work on your part

Hibernating Rhinos Ltd  

Oren Eini l CEO Mobile: + 972-52-548-6969

Office: +972-4-622-7811 l Fax: +972-153-4-622-7811

 


--
You received this message because you are subscribed to the Google Groups "RavenDB - 2nd generation document database" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Russ McClelland

unread,
Jun 20, 2017, 9:17:03 AM6/20/17
to RavenDB - 2nd generation document database
One of the subclasses requires a factory of cached instances. It is a strategy class that has about 8-10 pre-built instances. When the inbound stream is read, based on the type being "strategy", I need to look at one of the properties of the node ("Name") and then use the factory to look up the correct instance that is already in memory. The CustomCreationConverter doesn't have enough information available, because it only knows the type of the node, not the values (because it doesn't get the whole json node). The CustomConverter is too late because by the time it gets created, a new blank instance has been created (and it will immediately get garbage collected).
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+u...@googlegroups.com.

Oren Eini (Ayende Rahien)

unread,
Jun 20, 2017, 1:49:07 PM6/20/17
to ravendb
What does your converter look like?
To unsubscribe from this group and stop receiving emails from it, send an email to ravendb+unsubscribe@googlegroups.com.

Russ McClelland

unread,
Jun 23, 2017, 4:37:22 PM6/23/17
to RavenDB - 2nd generation document database

 I found the solution: create the converter for the abstract class, not the concrete class, since the abstract type is used in the declaration of the collection.
Reply all
Reply to author
Forward
0 new messages