Deserializing JSON object without setting “default” values?

So here’s a fun one. When serializing this object:

public class FiletDinner : IFood { public string Name { get; } = "Filet Dinner"; public List<IIngredient> RequiredIngredients { get; } = new List<IIngredient>{Pantry.GetIngredient(typeof(MashedPotatoes).FullName)}; public FiletDinner() { RequiredIngredients.Add(Pantry.GetIngredient(typeof(FreshOnion).FullName)); RequiredIngredients.Add(Pantry.GetIngredient(typeof(FrozenCarrot).FullName)); RequiredIngredients.Add(Pantry.GetIngredient(typeof(FiletMignon).FullName)); } } 

It serializes as you would expect. With 4 “required ingredients”.

However, when deserializing back into an object:

 public static object Deserialize(this string value) { var opts = new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.Objects, ConstructorHandling = ConstructorHandling.AllowNonPublicDefaultConstructor }; return JsonConvert.DeserializeObject(value, opts); } 

It calls all the constructors, then instead of “resetting” the list and adding just those items that were serialized into it, it leaves all the “defaults” in place, then adds the stuff that was serialized.

Thus now I have two of each item in the list.

I could fix this by creating an empty hidden constructor in the “FiletDinner” object:

 [JsonConstructor] private FiletDinner(bool nothing) { } 

And then making sure to ONLY set defaults in the “normal” constructor, but this would require a complete rework of a massive code base, as well as requiring that future developers are aware of this limitation.

I also tried using a CustomCreationConverter to at least get around the constructor:

 private class ConstructorLessConverter : CustomCreationConverter<object> { public override object Create(Type objectType) { return FormatterServices.GetSafeUninitializedObject(objectType); } } 

But this craps out on any lists that use interfaces instead of explicit objects.

Is there a clean way to simply “flush” default lists to ensure they only have those items that are deserialized into them?

submitted by /u/Javin007
[link] [comments]

Leave a Reply