Dot.Blog

Consulting DotNet C#, XAML, WinUI, WPF, MAUI, IA

Sérialisation JSON performante avec System.Text.Json et générateurs de source en .NET 9

Depuis .NET 7, System.Text.Json propose une fonctionnalité puissante : la génération de code à la compilation pour accélérer la (dé)sérialisation JSON, particulièrement utile en AOT ou dans des applications sensibles à la performance (MAUI, Blazor, services micro).. Comment en tirer profit ?

En .NET 9, cette approche est encore plus mature. Voici comment en tirer le meilleur.

⚡ Pourquoi utiliser la génération de source JSON ?

  • Évite la réflexion à l’exécution (incompatible avec AOT trimming)
  • Meilleures performances (initialisation et runtime)
  • Contrôle plus précis des modèles et des métadonnées
  • Support complet des structures complexes et des enums

🧪 Déclaration d’un contexte JSON source-gen

  1. Créer un fichier SerializationContext.cs
[JsonSerializable(typeof(User))]
[JsonSerializable(typeof(List<User>))]
public partial class AppJsonContext : JsonSerializerContext
{
}
  1. Activer la génération dans le projet
<PropertyGroup>
  <TargetFramework>net9.0</TargetFramework>
  <PublishTrimmed>true</PublishTrimmed>
  <TrimMode>link</TrimMode>
  <EnableTrimAnalyzer>true</EnableTrimAnalyzer>
  <EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
</PropertyGroup>

<ItemGroup>
  <Using Include="System.Text.Json.Serialization" />
</ItemGroup>

📦 Utilisation dans le code

var json = JsonSerializer.Serialize(user, AppJsonContext.Default.User);
var obj = JsonSerializer.Deserialize<User>(json, AppJsonContext.Default.User);

🧱 Exemple complet

public record User(string Name, int Age);

[JsonSerializable(typeof(User))]
[JsonSerializable(typeof(List<User>))]

public partial class AppJsonContext : JsonSerializerContext { }

// Dans votre code

var user = new User("Alice", 30);
string json = JsonSerializer.Serialize(user, AppJsonContext.Default.User);

Les types supportés doivent être connus à la compilation. Pas de type dynamique ou polymorphe ici.

🔧 Gestion des options (indentation, case, etc.)

[JsonSourceGenerationOptions(WriteIndented = true, PropertyNamingPolicy = JsonKnownNamingPolicy.CamelCase)]
[JsonSerializable(typeof(User))]
public partial class AppJsonContext : JsonSerializerContext { }

⚠️ Limitations

  • Incompatible avec les types dynamiques (object, ExpandoObject, etc.)
  • Nécessite des modèles stables et connus à l’avance
  • Pas de support natif pour la polymorphie complexe (contourner par des converters)

✅ Bonnes pratiques

  • Grouper les modèles dans un seul contexte
  • Nommer clairement les fichiers générés pour faciliter les diagnostics
  • Utiliser un contexte par domaine fonctionnel si besoin

📊 Comparatif : System.Text.Json vs Newtonsoft.Json

Critère

System.Text.Json (source-gen)

Newtonsoft.Json

Performance

✅ Très rapide (AOT-compatible)

⚠️ Moins performant (réflexion)

Support AOT / trimming

✅ Oui

❌ Non

Types dynamiques

❌ Non (via converter seulement)

✅ Oui

Polymorphisme

⚠️ Limité (avec configuration)

✅ Avancé

Génération de code à la compile

✅ Oui

❌ Non

Personnalisation fine

✅ Attributs et converters

✅ Très flexible

Compatibilité historique

⚠️ Partielle

✅ Très large

Choisissez System.Text.Json pour des apps modernes, rapides et AOT ; préférez Newtonsoft.Json si vous avez besoin de compatibilité maximale ou de cas très dynamiques.

🔚 Conclusion

La source generation avec System.Text.Json en .NET 9 permet une sérialisation rapide, sûre et compatible AOT. Elle est idéale pour les apps MAUI, Blazor, ou les API microservices modernes.

Stay Tuned !

Faites des heureux, PARTAGEZ l'article !