Click here to Skip to main content
Click here to Skip to main content

Dynamic types with JSON.NET

, 4 Aug 2013
Rate this:
Please Sign up or sign in to vote.
Using JSON.NET to deserialize collections of dynamic-type objects.

Introduction   

This article shows how to deserialize JSON into a collection of objects of dynamic types with JSON.NET 

Background  

It is often asked by those just starting to use JSON.NET - how to deserialize a collection of objects for which we only know the base type, while the actual type needs to be determined during the transformation, based on JSON data? 

It is quite a fundamental question about JSON.NET, which I intend to answer here in the most simplistic way.    

Let's consider two typical JSON examples you are likely to encounter:  

  • Deserializing a JSON array into type List 
  • Deserializing JSON list of objects into type Dictionary 

We start with declaration of the classes that expect the data: 

public class TestBase
{
}

public class TestA : TestBase
{
    public string text;
}

public class TestB : TestBase
{
    public DateTime date;
} 

For a list of type List<TestBase> you may use JSON like shown below:  

[
    {
    type: "testA",
    text: "something"
    },
    {
    type: "testB",
    date: "02/03/2010"
    }
]

And for a dictionary of type Dictionary<int, TestBase> you might use JSON as follows:   

{
    1:
    {
    type: "testA",
    text: "something"
    },
    2:
    {
    type: "testB",
    date: "02/03/2010"
    }
}

In both JSON examples we added attribute type to tell us which object type can contain the data. And we just need a way to pass it on to JSON deserializer for correct type instantiation.  The following chapter explains how to do that. 

Using the code 

We assume here that you already have a project where you are using JSON.NET, because if not, this tip isn't for you at all.    

In order to convert JSON into the aforementioned List and Dictionary types, use code as shown below: 

JsonVirtualConverter<TestBase> jvc = new JsonVirtualConverter<TestBase>("type", t =>
{
    switch (t)
    {
        case "testA":
            return new TestA();
        case "testB":
            return new TestB();
        default:
            return null;
    }
});

// Reading JSON from two files:
string list = File.ReadAllText("../../JSON/ListData.json");
string dict = File.ReadAllText("../../JSON/DictData.json");

// Now we can read and transform all data automatically:
List<TestBase> a = JsonConvert.DeserializeObject<List<TestBase>>(list, jvc);
Dictionary<int, TestBase> b = JsonConvert.DeserializeObject<Dictionary<int, TestBase>>(dict, jvc);

Above we set up our instantiation object to create the right type of objects based on attribute type, and then let JSON.NET take care of the rest.    

For both transformations we passed an instance of JsonVirtualConverter, which is a very simple class attached to this article, created just to solve the exact problem this article describes.  

Points of Interest   

Currently, playing with advanced JSON stuff as part of a web project. 

Also, by publishing this tip I'm trying to get some attention from the author of JSON.NET, James Newton-King, to convince him to include this simple class JsonVirtualConverter into the next release of JSON.NET. He seems to be very hard to reach Smile | :)   

History

  • August 04, 2013 - Initial Draft  

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Vitaly Tomilov
Software Developer (Senior) Sibedge IT
Ireland Ireland
My online CV: cv.vitalytomilov.com

Comments and Discussions

 
-- There are no messages in this forum --
| Advertise | Privacy | Mobile
Web02 | 2.8.140721.1 | Last Updated 4 Aug 2013
Article Copyright 2013 by Vitaly Tomilov
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid