1

I'm trying to serialize the IAnimal instance object to json using Json.NET. Class structure:

public class Dog : IAnimal {
    public int Width { get; set; }
    public double Bark { get; set; }
}

public class Cat : IAnimal {
    public int Width { get; set; }
    public double Meow { get; set; }
}

public interface IAnimal {
    int Width { get; set; }
}

public class AnimalContainer {
    public IAnimal Animal { get; set; }
}

Tried this way (please notice I use 'TypeNameHandling.Auto' as I found in other threads):

public void IAnimal_ShouldBeJsonSerializable() {
        var animal = new AnimalContainer {Animal = new Dog {Bark = 5, Width = 2}};
        var json = JsonConvert.SerializeObject(animal,
            new JsonSerializerSettings{TypeNameHandling = TypeNameHandling.Auto});
        var deserializedAnimal = JsonConvert.DeserializeObject<AnimalContainer>(json);
    }

but is throwing me exception that "Could not create an instance of type IAnimal, Type is an interface or abstract class and cannot be instantiated". But the json contains the concrete type information!

How can I make it work?

mbudnik
  • 2,087
  • 15
  • 34

1 Answers1

2

It does not look like you are passing the serializer settings to your DeserializeObject call. You need to include the TypeNameHandling both on Serialize and Deserialize.

var animal = new AnimalContainer { Animal = new Dog { Bark = 5, Width = 2 } };
var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Auto };
var json = JsonConvert.SerializeObject(animal, settings);
var deserializedAnimal = JsonConvert.DeserializeObject<AnimalContainer>(json, settings);
Console.WriteLine(deserializedAnimal.Animal.GetType().Name);
Brian Rogers
  • 125,747
  • 31
  • 299
  • 300
  • Hey, thanks for fast response. It works when animal is an interface. What about an abstract class? Getting the same exception again. – mbudnik Oct 27 '14 at 23:35
  • Should still work; I just tried it by creating an abstract `BaseAnimal` class and making both `Dog` and `Cat` inherit from it. (I moved the `Width` property to the base.) Then I changed the `Animal` property in the `AnimalContainer` to be a `BaseAnimal'. I ran the above serialize/deserialize code, and it worked fine. – Brian Rogers Oct 27 '14 at 23:45