Effacer les collections avant d’append des éléments lors du remplissage d’objects existants

J’ai un object qui a plusieurs propriétés de collection définies avec getter public mais setter privé. Dans ce cas, JsonConvert.PopulateObject ajoute les éléments désérialisés à ces collections en laissant les éléments existants intacts.

J’ai besoin d’un comportement lorsque ces collections de membres sont effacées avant la désérialisation.

J’ai essayé d’effacer manuellement les collections avec une méthode marquée avec l’atsortingbut [OnDeserializing] .

Le problème avec cette approche est que les collections seront toujours effacées même si la propriété collection n’existe pas dans la chaîne JSON.

J’ai besoin d’un moyen de ne supprimer que les collections réellement définies dans la chaîne JSON. Ceux qui ne sont pas définis doivent restr intacts.

Merci

Bon, après un voyage dans les sources Json.NET, j’ai trouvé la solution suivante en héritant d’un résolveur de contrat personnalisé de DefaultContractResolver .

J’avais besoin de remplacer la création du contrat de masortingce pour append un rappel de désérialisation. À ce stade, le rappel reçoit l’instance de collection concrète afin que nous puissions la manipuler (dans ce cas, effacez-la).

Tant que je peux le déterminer, son utilisation est sûre, mais n’hésitez pas à avertir de tout inconvénient de cette méthode.

Remarque: Suis-je le seul à penser que cela devrait probablement être le comportement par défaut?

 public class CollectionClearingContractResolver : DefaultContractResolver { protected override JsonArrayContract CreateArrayContract(Type objectType) { var c = base.CreateArrayContract(objectType); c.OnDeserializingCallbacks.Add((obj, streamingContext) => { var list = obj as IList; if (list != null && !list.IsReadOnly) list.Clear(); }); return c; } } ... public class Test { public List List { get; private set; } public Test() { List = new List(); } } ... var myObj = new Test(); myObj.List.AddRange(new[] {1,2,3}); var listReference = myObj.List; JsonConvert.PopulateObject("{ List: [4, 5, 6] }", myObj, new JsonSerializerSettings { ContractResolver = new CollectionClearingContractResolver(), }); myObj.List.ShouldEqual(listReference); // didn't recreate list myObj.List.Count.ShouldEqual(3); myObj.List.SequenceEqual(new[] { 4, 5, 6}).ShouldBeTrue();