58 votes

JSON.net ContractResolver vs. JsonConverter

Je travaille avec JSON.net depuis un certain temps. J'ai écrit à la fois des convertisseurs personnalisés et des résolveurs de contrat personnalisés (généralement à partir de la modification d'exemples sur S.O. et le site Web de Newtonsoft), et ils fonctionnent bien.

Le problème, c'est qu'en dehors des exemples, je ne vois guère d'explications sur le moment où je dois utiliser l'un ou l'autre (ou les deux) pour le traitement. Par ma propre expérience, j'ai essentiellement déterminé que les résolveurs de contrat sont plus simples, donc si je peux faire ce dont j'ai besoin avec eux, je vais dans cette direction ; sinon, j'utilise des JsonConverters personnalisés. Mais, je sais aussi que les deux sont parfois utilisés ensemble, ainsi les concepts deviennent plus opaques.

Questions :

  1. Existe-t-il une source qui distingue quand il faut utiliser l'un ou l'autre ? Je trouve que la documentation de Newtonsoft n'est pas claire quant à la façon dont les deux sont différenciés ou quand utiliser l'un ou l'autre.
  2. Quel est le pipeline de commande entre les deux ?

159voto

Brian Rogers Points 12160

Excellente question. Je n'ai pas vu de documentation claire indiquant quand il est préférable d'écrire un fichier personnalisé ContractResolver ou un JsonConverter pour résoudre un type particulier de problème. Ils font vraiment des choses différentes, mais il y a un certain chevauchement entre les types de problèmes qui peuvent être résolus par chacun. J'ai écrit un bon nombre d'articles sur chacun d'eux en répondant à des questions sur StackOverflow, de sorte que l'image est devenue un peu plus claire pour moi au fil du temps. Voici mon point de vue à ce sujet.

Résolveur de contrat

Un résolveur de contrat est toujours utilisé par Json.Net, et régit le comportement de sérialisation/désérialisation à un niveau général. S'il n'y a pas de résolveur personnalisé fourni dans les paramètres, alors l'attribut DefaultContractResolver est utilisé. Le résolveur est chargé de déterminer :

  • ce que contrat chaque type a (c'est-à-dire s'agit-il d'une primitive, d'un tableau/liste, d'un dictionnaire, d'une dynamique ), JObject , un vieil objet, etc ;)
  • quelles sont les propriétés du type (le cas échéant) et quels sont leurs noms, types et accessibilité ;
  • ce que attributs ont été appliquées (par exemple [JsonProperty] , [JsonIgnore] , [JsonConverter] etc.), et
  • comment ces attributs doivent affecter la (dé)sérialisation de chaque propriété (ou classe).

D'une manière générale, si vous souhaitez personnaliser un aspect de la sérialisation ou de la désérialisation dans un large éventail de classes, vous devrez probablement utiliser un fichier ContractResolver pour le faire. Voici quelques exemples de choses que vous pouvez personnaliser à l'aide d'une ContractResolver :

JsonConverter

Contrairement à un ContractResolver le centre d'intérêt d'un JsonConverter est plus étroite : elle est vraiment destinée à gérer la sérialisation ou la désérialisation d'un seul type ou d'un petit sous-ensemble de types apparentés. En outre, il travaille à un niveau inférieur à celui d'un résolveur. Lorsqu'un convertisseur se voit confier la responsabilité d'un type, il a un contrôle total sur la manière dont le JSON est lu ou écrit pour ce type : il utilise directement les fonctions JsonReader y JsonWriter pour faire son travail. En d'autres termes, il peut modifier le forme du JSON pour ce type. Dans le même temps, un convertisseur est découplé de la "vue d'ensemble" et n'a pas accès aux informations contextuelles telles que le parent de l'objet (dé)sérialisé ou les attributs de propriété qui ont été utilisés avec lui. Voici quelques exemples de problèmes que vous pouvez résoudre avec un JsonConverter :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X