How to deserialize polymorphic collections in JsonFX?

1.5k Views Asked by At

My JsonFX serialization code works, but the object that I'm serializing contains a list of polymorphic entities, and they're all deserialized as their base type and not their actual type.

Here's my serialization code:

public static string Serialize(System.Object obj)
{
    StringBuilder builder = new StringBuilder();
    using (TextWriter textWriter = new StringWriter(builder))
    {
        JsonWriter writer = new JsonWriter(textWriter);
        writer.Write(obj);

        return builder.ToString();
    }
}

public static T Deserialize<T>(string json)
{
    using (TextReader textReader = new StringReader(json))
    {
        var jsonReader = new JsonReader(textReader);
        return jsonReader.Deserialize<T>();
    }
}

As you can see it's pretty straightforward. I'm also not decorating my classes with any attributes or anything special to make them serializable. Besides the polymorphic problem, it all just seems to be working properly.

So how can I get my polymorphic types to deserialize properly?.

Thanks.

1

There are 1 best solutions below

0
On

You need to turn on type hinting. Here's example code (this is relevant to JsonFx v1.4, may or may not work with your version):

    StringBuilder result = new StringBuilder(string.Empty);

    JsonWriterSettings settings = JsonDataWriter.CreateSettings(true);
    settings.TypeHintName = "__type";

    JsonWriter writer = new JsonWriter(result, settings);

    writer.Write(obj);

    return result.ToString();

This will add extra data to your JSON string which looks something like:

"__type": "MyNamespace.MyClass, MyAssembly",

Which means it finds out what derived type it is based on the class name. If you change your class name or namespace name, it won't work anymore. Worse, you can't deserialize from your old JSON text data anymore, unless you mass replace all occurrences of the old class name and replace it with the new.

So you have to be careful with it.

EDIT: Forgot to mention that you have to edit the source code of JsonFx for this to work. In JsonReader.cs, find the ReadArray method:

Change:

object value = this.Read(arrayItemType, isArrayTypeAHint);

to:

object value = this.Read(null, false);

This will ensure that JsonFx will always attempt to figure out the type of each element in an array/list. If you want this to work for just single variables, well you'd need to do the changes on the appropriate code (haven't tried that).