Princess
Princess

Reputation: 443

Json.Net Deserialize an object dynamically?

I am trying to deserialize an object using Json.Net. I have a simple object called MyObject that holds a serialized object in MyObject.Body. I am storing the class type in MyObject.ClassType. I do not want to write a giant switch statement to figure out what type to deserialize to. Can I do this dynamically?

string value = "fullClassName";
switch (value)
{
    case "Cat":
        var cat = JsonConvert.DeserializeObject<Cat>(myObject.Body);
        break;
    case "Dog":
        var dog = JsonConvert.DeserializeObject<Dog>(myObject.Body);
        break;
}


public class MyObject
{
    public string Body { get; set; }
    public string ClassType { get; set; }
}    


var myAnimal = JsonConvert.DeserializeObject<1of10TypesOfObjects> (myObject.Body);

Upvotes: 0

Views: 726

Answers (3)

Kenneth Tsai
Kenneth Tsai

Reputation: 136

I put my answer on.

string typeName = "ConsoleApplication1.Cat";
var type = Type.GetType(typeName);
var myObject = new MyObject {Body = "{ Color: 'red' }"};

var res = JsonConvert.DeserializeObject(myObject.Body, type);

Please make sure the type name string must be a fullname, which included the namespace. Eg. "ConsoleApplication1.Cat". And you must need to do some exception handling to avoid the type not found if someone enter the wrong typeName.

Upvotes: 1

Dustin Kingen
Dustin Kingen

Reputation: 21275

You can do that with:

JsonConvert.DeserializeObject(string value, Type type)

This will deserialize the JSON using the type information rather than a generic type parameter.

var myObjects = new List<MyObject>
{
    new MyObject
    {
        ClassType = typeof(Cat).FullName,
        Body = JsonConvert.SerializeObject(new Cat { Fluffiness = 10 })
    },
    new MyObject
    {
        ClassType = typeof(Dog).FullName,
        Body = JsonConvert.SerializeObject(new Dog { Loudness = 3 })
    }
};

List<object> objects =
    myObjects
        .Select(myObject =>
            JsonConvert.DeserializeObject(
            myObject.Body,
            typeof(Cat).Assembly.GetType(myObject.ClassType)))
        .ToList();

See:

Upvotes: 2

tuq
tuq

Reputation: 1538

Sure, you can do it. Please make sure the serialized string is corresponding to the type you try to de-serialize. For example:

class Dog
{
    public string Name { get; set; }
}

class Cat
{
    public string Type { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        Dog dog = new Dog { Name = "My Dog" };
        string strDog = JsonConvert.SerializeObject(dog);

        Cat cat = new Cat { Type = "My Cat" };
        string strCat = JsonConvert.SerializeObject(cat);

        var dog2 = JsonConvert.DeserializeObject<Dog>(strDog);
        var cat2 = JsonConvert.DeserializeObject<Cat>(strCat);
        Console.WriteLine(cat2.Type); 
        Console.WriteLine(dog2.Name);          

    }
}

Upvotes: 0

Related Questions