J'ai une classe qui a un constructeur par défaut et aussi un constructeur surchargé qui prend dans un ensemble de paramètres. Ces paramètres correspondent aux champs de l'objet et sont affectés lors de la construction. À ce stade, j'ai besoin du constructeur par défaut à d'autres fins, je voudrais donc le conserver si je le peux.
Mon problème: si je supprime le constructeur par défaut et passe la chaîne JSON, l'objet se désérialise correctement et transmet les paramètres du constructeur sans aucun problème. Je finis par récupérer l'objet peuplé comme je m'y attendais. Cependant, dès que j'ajoute le constructeur par défaut dans l'objet, lorsque j'appelle, JsonConvert.DeserializeObject<Result>(jsontext)
les propriétés ne sont plus remplies.
À ce stade, j'ai essayé d'ajouter new JsonSerializerSettings(){CheckAdditionalContent = true}
à l'appel de désérialisation. cela n'a rien fait.
Une autre note. les paramètres du constructeur correspondent exactement aux noms des champs, sauf que les paramètres commencent par une lettre minuscule. Je ne pense pas que cela importerait car, comme je l'ai mentionné, la désérialisation fonctionne bien sans constructeur par défaut.
Voici un échantillon de mes constructeurs:
public Result() { }
public Result(int? code, string format, Dictionary<string, string> details = null)
{
Code = code ?? ERROR_CODE;
Format = format;
if (details == null)
Details = new Dictionary<string, string>();
else
Details = details;
}
Réponses:
Json.Net préfère utiliser le constructeur par défaut (sans paramètre) sur un objet s'il y en a un. S'il existe plusieurs constructeurs et que vous souhaitez que Json.Net en utilise un autre que celui par défaut, vous pouvez ajouter l'
[JsonConstructor]
attribut au constructeur que vous souhaitez que Json.Net appelle.Il est important que les noms des paramètres du constructeur correspondent aux noms de propriété correspondants de l'objet JSON (en ignorant la casse) pour que cela fonctionne correctement. Cependant, vous n'avez pas nécessairement besoin d'un paramètre de constructeur pour chaque propriété de l'objet. Pour les propriétés d'objet JSON qui ne sont pas couvertes par les paramètres du constructeur, Json.Net essaiera d'utiliser les accesseurs de propriété publique (ou les propriétés / champs marqués par
[JsonProperty]
) pour remplir l'objet après sa construction.Si vous ne souhaitez pas ajouter d'attributs à votre classe ou si vous ne contrôlez pas le code source de la classe que vous essayez de désérialiser, une autre alternative consiste à créer un JsonConverter personnalisé pour instancier et peupler votre objet. Par exemple:
Ensuite, ajoutez le convertisseur à vos paramètres de sérialiseur et utilisez les paramètres lorsque vous désérialisez:
la source
JsonConverter
pour votre classe. Cela supprimerait la dépendance, mais vous devrez ensuite gérer l'instanciation et le remplissage de l'objet vous-même dans le convertisseur. Il pourrait également être possible d'écrire une coutumeContractResolver
qui dirigerait Json.Net pour utiliser l'autre constructeur en changeant sonJsonObjectContract
, mais cela pourrait s'avérer un peu plus compliqué qu'il n'y paraît.using Newtonsoft.Json;
Un peu tard et pas tout à fait adapté ici, mais je vais ajouter ma solution ici, car ma question avait été fermée comme un double de celle-ci, et parce que cette solution est complètement différente.
J'avais besoin d'un moyen général pour demander
Json.NET
de préférer le constructeur le plus spécifique pour un type de structure défini par l'utilisateur, afin que je puisse omettre lesJsonConstructor
attributs qui ajouteraient une dépendance au projet où chaque structure de ce type est définie.J'ai un peu d'ingénierie inverse et implémenté un résolveur de contrat personnalisé où j'ai remplacé la
CreateObjectContract
méthode pour ajouter ma logique de création personnalisée.Je l'utilise comme ça.
la source
objectType.IsValueType
) et cela fonctionne très bien, merci!Sur la base de certaines des réponses ici, j'ai écrit un
CustomConstructorResolver
pour une utilisation dans un projet en cours, et j'ai pensé que cela pourrait aider quelqu'un d'autre.Il prend en charge les mécanismes de résolution suivants, tous configurables:
Newtonsoft.Json.JsonConstructorAttribute
.Voici la version complète avec la documentation XML comme base: https://gist.github.com/maverickelementalch/80f77f4b6bdce3b434b0f7a1d06baa95
Commentaires appréciés.
la source
Le comportement par défaut de Newtonsoft.Json va trouver les
public
constructeurs. Si votre constructeur par défaut est uniquement utilisé pour contenir la classe ou le même assembly, vous pouvez réduire le niveau d'accès àprotected
ouinternal
pour que Newtonsoft.Json choisisse lepublic
constructeur souhaité .Certes, cette solution est plutôt très limitée à des cas spécifiques.
la source
Solution:
Modèle:
la source