Nouvelles Du Monde

Nouveau dans .NET 7.0 [24]: Polymorphisme lors de la sérialisation avec System.Text.Json

Nouveau dans .NET 7.0 [24]: Polymorphisme lors de la sérialisation avec System.Text.Json

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}.";
 }
}

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"}

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).

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.

La prochaine partie de cette série, qui sortira la semaine prochaine, concerne le polymorphisme dans la désérialisation JSON.


(carte)

Vers la page d’accueil



#Nouveau #dans #.NET #Polymorphisme #lors #sérialisation #avec #System.Text.Json
1690609570

Facebook
Twitter
LinkedIn
Pinterest

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.

ADVERTISEMENT