JSON et C# dynamic : pourquoi c'est toujours une douleur (et comment la soigner)
\n\nAvez-vous déjà regardé une réponse JSON d'une API en pensant : « Mon Dieu, pourquoi es-tu si compliqué ? » Surtout quand la structure des données change à chaque fois, comme la météo à Saint-Pétersbourg. L'exemple classique est la réponse d'un service externe où les champs peuvent être tantôt des chaînes, tantôt des tableaux, voire null. Ou quand vous devez rapidement analyser du JSON, mais créer une classe dédiée revient à usiner une puce avec un microscope.
C'est précisément pour ces cas que C# offre la magie de dynamic. La question « Deserialize JSON into C# dynamic object ? » sur Stack Overflow a recueilli des milliers de vues — et ce n'est pas un hasard. En 2025, alors que les microservices et les API dynamiques sont devenus la norme, savoir travailler rapidement et flexiblement avec JSON est un super-pouvoir pour tout développeur.
Dans cet article, nous allons passer en revue les meilleures pratiques de désérialisation JSON en objet dynamic en C#. Pas de théorie ennuyeuse, seulement du code, des exemples et des astuces concrètes. C'est parti !
\n\nPourquoi dynamic ? Et pas simplement JObject ?
\n\nBonne question. En C#, il existe JObject (de Newtonsoft.Json) et JsonDocument (de System.Text.Json). Ils savent aussi analyser JSON « à la volée ». Mais dynamic apporte une chose importante : du sucre syntaxique.
Comparez :
\n\n// Avec JObject\nvar json = JObject.Parse(rawJson);\nvar name = (string)json["user"]["name"];\n\n// Avec dynamic\ndynamic obj = JsonConvert.DeserializeObject<dynamic>(rawJson);\nvar name = obj.user.name;\n\n\nLa deuxième option se lit comme du code normal, pas comme « prends la clé, caste le type, vérifie null ». C'est particulièrement pratique quand le JSON est profondément imbriqué.
\n\nMéthode 1 : La classique — Newtonsoft.Json (Json.NET)
\n\nOui, nous sommes en 2025, mais Newtonsoft.Json est toujours bien vivant. De nombreux projets legacy, et même certains projets modernes, l'utilisent encore. Pourquoi ? Flexibilité, extensibilité et des millions de paramètres.
\n\nExemple de base
\n\nusing Newtonsoft.Json;\n\nstring json = @"\n{\n 'name': 'Alexei',\n 'age': 30,\n 'skills': ['C#', 'Python', 'SQL'],\n 'address': {\n 'city': 'Moscou',\n 'zip': 101000\n }\n}";\n\ndynamic obj = JsonConvert.DeserializeObject<dynamic>(json);\n\nConsole.WriteLine(obj.name); // Alexei\nConsole.WriteLine(obj.age); // 30\nConsole.WriteLine(obj.skills[0]); // C#\nConsole.WriteLine(obj.address.city); // Moscou\n\n\nTout est simple et élégant. Mais il y a un hic : en travaillant avec dynamic, vous perdez IntelliSense et la vérification de type à la compilation. Une erreur dans le nom d'un champ n'apparaîtra qu'à l'exécution. Donc :
- \n
- Utilisez
dynamicuniquement pour lire des données que vous ne contrôlez pas. \n - Encapsulez toujours les appels dans des blocs try-catch. \n
- N'en abusez pas — si la structure JSON est stable, il est préférable de créer une classe DTO. \n
Méthode 2 : La moderne — System.Text.Json
\n\nDepuis .NET Core 3.0, Microsoft promeut System.Text.Json — rapide, natif, sans dépendances externes. En 2025, c'est la norme pour les nouveaux projets.
Mais il y a un piège : System.Text.Json ne sait pas désérialiser en dynamic « prêt à l'emploi ». Il faudra un peu de gymnastique.
Option A : Via JsonDocument et ExpandoObject
\n\nusing System.Text.Json;\nusing System.Dynamic;\n\nstring json = @"{""name"":""Hélène"",""age"":25,""active"":true}";\n\nusing JsonDocument doc = JsonDocument.Parse(json);\ndynamic obj = ConvertToExpando(doc.RootElement);\n\nConsole.WriteLine(obj.name); // Hélène\nConsole.WriteLine(obj.age); // 25\nConsole.WriteLine(obj.active); // True\n\nstatic ExpandoObject ConvertToExpando(JsonElement element)\n{\n var expando = new ExpandoObject();\n var dict = (IDictionary<string, object>)expando;\n\n foreach (var property in element.Enumera