Kann Newtonsoft eine Liste geerbter Objekte oder Objekte der Unterklasse ordnungsgemäß deserialisieren? [Duplikat]
Wenn ich mit Newtonsoft (mit TypeNameHandling.All
) a serialisiere List<Animal>
, das a <Cat>
und a enthält <Dog>
, List<Animal>
verlieren sie beim Vererben der Zeichenfolge zurück in a ihre Vererbung und werden gerecht <Animals>
.
Gibt es eine Möglichkeit für Newtonsoft, die Unterklassen beizubehalten, wenn sie wieder in eine List
ihrer Elternklassen deserialisiert werden ?
Hier sind die Objekte:
public class Zoo
{
public List<Animal> Animals;
public Zoo()
{
Animals = new List<Animal>();
}
}
public class Animal
{
}
public class Dog : Animal
{
}
public class Cat : Animal
{
}
}
Hier ist der Test:
static void Main(string[] args)
{
var zoo = new Zoo();
var dog = new Dog();
var cat = new Cat();
zoo.Animals.Add(dog);
zoo.Animals.Add(cat);
var json = JsonConvert.SerializeObject(zoo, Formatting.None,
new JsonSerializerSettings
{
TypeNameHandling = TypeNameHandling.All
});
var newZoo = JsonConvert.DeserializeObject<Zoo>(json);
}
So sieht die ursprüngliche Zoo.Animal-Liste aus (beachten Sie die Hunde- und Katzentypen):

Sobald es serialisiert ist, können wir sehen, dass die Unterklassen korrekt enthalten sind. Sollte genug Information sein, um es wieder in ein ähnliches Objekt zu deserialisieren:
{
"$type": "Sample.Sandbox.Zoo, Sample.Sandbox", "Animals": { "$type": "System.Collections.Generic.List`1[[Sample.Sandbox.Animal, Sample.Sandbox]], System.Private.CoreLib",
"$values": [ { "$type": "Sample.Sandbox.Dog, Sample.Sandbox"
},
{
"$type": "Sample.Sandbox.Cat, Sample.Sandbox"
}
]
}
}
Aber wenn es deserialisiert wird, sind die Dog
und Cat
weg. Sie sind gerade Animals
jetzt:

Gibt es eine Möglichkeit für Newtonsoft, den JSON ordnungsgemäß zu deserialisieren und die Unterklassentypen beizubehalten?
Vielen Dank für alle Tipps.
Antworten
Sie müssen Einstellungen sowohl für den Serializer als auch für den Deserialiser hinzufügen.
Versuche dies:
JsonSerializerSettings settings = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All };
var json = JsonConvert.SerializeObject(zoo,settings);
var newZoo = JsonConvert.DeserializeObject<Zoo>(json,settings);
foreach (var currentAnimal in newZoo.Animals)
{
Console.WriteLine(currentAnimal.GetType().Name);
}
Sollte ausdrucken: Dog Cat