If you’re using Json.NET to serialize objects which involve inheritance hierarchies, there’s a little issue you might run into.
Let’s say we have a class Person:
public class Person { public string Name { get; set; } }
…and we also have another class Employee which derives from Person:
public class Employee : Person { public decimal Salary { get; set; } }
Then I can write the following little Console Application (in which Json.NET is installed via NuGet):
var employee = new Employee() { Name = "John", Salary = 1000m }; var json = JsonConvert.SerializeObject(employee); var deserialized = JsonConvert.DeserializeObject<Person>(json);
We’re serializing an Employee (which derives from Person), and then deserializing into a Person (the base class). Due to polymorphism, we’d expect the result to hold a reference to an Employee instance complete with Salary. Alas, this is not the case:
As you can see, the result is actually of type Person, and the Salary goes missing in the deserialization.
Apparently the solution is to turn on Type Name Handling. The code is thus transformed:
var settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }; var employee = new Employee() { Name = "John", Salary = 1000m }; var json = JsonConvert.SerializeObject(employee, settings); var deserialized = JsonConvert.DeserializeObject<Person>(json, settings);
Once we create an instance of JsonDerializerSettings with TypeNameHandling turned on, we can pass that object as a paramater in the serialization/deserialization methods to obtain the correct result:
As you can see, the deserialized result is now an Employee, complete with Salary. You’ll also notice that the actual serialized JSON has changed: there is now type information in it, and that’s what allows the correct type to be deserialized.
So why is this functionality not enabled by default? I can only guess that it’s for performance reasons.