2023-07-28 11:22:00
Dans la bibliothèque JSON System.Text.Json
l’annotation est disponible depuis la version 7.0 [JsonDerivedType]
. Avec cela, vous pouvez déclarer ce que l’on appelle des discriminateurs de type pour la classe de base et les classes dérivées pour une classe de base. Celles-ci sont prises en compte lors de la sérialisation et de la désérialisation.
Publicité
docteur Holger Schwichtenberg est expert en technologie en chef chez MAXIMAGO, qui propose un développement de logiciels axé sur l’innovation et l’expérience, y compris dans des domaines hautement critiques liés à la sécurité. Il est également à la tête du réseau d’experts www.IT-Visions.de, qui soutient de nombreuses moyennes et grandes entreprises avec des conseils et une formation dans le développement et l’exploitation de logiciels avec 38 experts renommés.
Exemple : Étant donné une classe de base Person
et une classe dérivée Consultant
.
[JsonDerivedType(typeof(Person), typeDiscriminator: "P")]
[JsonDerivedType(typeof(Consultant), typeDiscriminator: "C")]
public class Person
{
public required int ID { get; set; }
public required string Name { get; set; }
public override string ToString()
{
return $"Person {Name}";
}
}
public class Consultant : Person
{
public string? Company { get; set; }
public override string ToString()
{
return $"Consultant {Name} arbeitet bei {Company}.";
}
}
La sérialisation produit la propriété personnalisée $type
Maintenant, si vous créez une instance de Person et la sérialisez en JSON
Person p = new Person() { ID = 123, Name = "Holger Schwichtenberg" };
var json1 = JsonSerializer.Serialize(p);
vous obtenez cette chaîne JSON avec l’ajout “$type”:”P”:
Publicité
{"$type":"P","ID":123,"Name":"Holger Schwichtenberg"}
Sans préciser [JsonDerivedType]
aurait obtenu :
{"ID":123,"Name":"Holger Schwichtenberg"}
De même, la sérialisation d’un objet consultant donne ici un “C”, même si la variable est du type de base de la classe de base Person, c’est-à-dire
Person c = new Consultant() { ID = 123, Name = "Holger Schwichtenberg", Company = "www.IT-Visions.de" };
var json2 = JsonSerializer.Serialize(c);
livre
{"$type":"C","Company":"www.IT-Visions.de","ID":123,"Name":"Holger Schwichtenberg"}
Sans préciser [JsonDerivedType]
vous n’obtiendriez que ceci à nouveau:
{"ID":123,"Name":"Holger Schwichtenberg"}
Si on devait déclarer la variable sans discriminateur de type c
sur Consultant
au lieu de sur Person
taper
Consultant c = new Consultant() { ID = 123, Name = "Holger Schwichtenberg", Company = "www.IT-Visions.de" };
var json2 = JsonSerializer.Serialize(c);
alors le résultat serait
{"Company":"www.IT-Visions.de","ID":123,"Name":"Holger Schwichtenberg"}
Cela signifie: [JsonDerivedType]
sert non seulement à obtenir la spécification supplémentaire $type dans la chaîne JSON, mais également à sérialiser les propriétés supplémentaires d’un type dérivé si le code utilise une classe de base au lieu du type concret. [JsonDerivedType]
prend ainsi en charge la programmation polymorphe.
Important : s’il existe une autre classe dérivée Developer
existe, mais pour lequel il n’y a pas d’annotation [JsonDerivedType]
existe dans la classe de base
public class Developer : Person
{
public string? Company { get; set; }
public override string ToString()
{
return $"Developer {Name} entwickelt bei {Company}";
}
}
alors il y a une erreur d’exécution
Runtime type 'Developer' is not supported by polymorphic type 'Person'
,
si vous essayez ceci:
Person d = new Developer() { ID = 123, Name = "Holger Schwichtenberg", Company = "MAXIMAGO GmbH" };
var json3 = JsonSerializer.Serialize(d);
Vous pouvez modifier ce comportement. Avec un supplément
[JsonPolymorphic(UnknownDerivedTypeHandling = JsonUnknownDerivedTypeHandling.FallBackToBaseType)]
Sur la classe de base, vous pouvez toujours sérialiser la propriété person de l’objet développeur s’il n’y a pas de discriminateur de type approprié :
{"$type":"P","ID":123,"Name":"Holger Schwichtenberg"}
Plus d’options
Le typeDiscriminator
peut aussi être un nombre au lieu d’une chaîne de caractères :
[JsonDerivedType(typeof(Person), typeDiscriminator: 0)]
[JsonDerivedType(typeof(Consultant), typeDiscriminator: 1)]
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public override string ToString()
{
return $"Person {Name}";
}
}
Au lieu de $type
vous pouvez utiliser un nom différent dans la sérialisation et la désérialisation en utilisant l’annotation [JsonPolymorphic]
déclaré sur la classe de base :
[JsonDerivedType(typeof(Person), typeDiscriminator: "P")]
[JsonDerivedType(typeof(Consultant), typeDiscriminator: "C")]
[JsonPolymorphic(TypeDiscriminatorPropertyName = "$class")] // Standard ist $type
public class Person
{
public int ID { get; set; }
public string Name { get; set; }
public override string ToString()
{
return $"Person {Name}";
}
}
Dans les résolveurs d’informations de type abordés dans la partie 22, vous pouvez également utiliser le comportement polymorphe via typeInfo.PolymorphismOptions
configurer (voir le Article de blog Microsoft sur System.Text.Json).
Disponibilité
System.Text.Json
est avec .NET 7.0 Publié en tant que package NuGetmais fonctionne également sous .NET Standard 2.0 et donc également sur .NET Core 2.x/3.x et .NET 5.0/.NET 6.0 sur le .NET Framework classique à partir de la version 4.6.2.
perspectives
La prochaine partie de cette série, qui sortira la semaine prochaine, concerne le polymorphisme dans la désérialisation JSON.
(carte)
#Nouveau #dans #.NET #Polymorphisme #lors #sérialisation #avec #System.Text.Json
1690609570