I have a recursive class (tree hierarchy), that derives from a list, that has the children, and itself, populated from deserialization in JSON.NET.
The TLDR version is that I want to populate a variable in the children, from the parent, on each level of this class where it exists, without using $ref variables from JSON.NET (saves space when storing to a cookie).
For those that followed my question from yesterday, this may look like a duplicate, but it is not. It is the same code, but the old question revolved around setters in JSON not being fired (resolved), and the answer brought about this question (more aptly worded).
The initial call would be:
_Items = Cookies.Instance.GetJObject<CartItems>(COOKIE, jsonSetting);
Which calls:
public T GetJObject<T>(string cookieName, JsonSerializerSettings jset = null)
{
string cookieContent = Get(cookieName);
return JsonConvert.DeserializeObject<T>(cookieContent, jset);
}
The custom converter class is as follows:
public class JsonCartConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(CartItem).IsAssignableFrom(objectType);
}
public override bool CanWrite
{
get
{
return false;
}
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
JObject obj = JObject.Load(reader);
var type = obj["t"] != null ? (CARTITEMTYPE)obj["t"].Value<int>() : CARTITEMTYPE.GENERIC;
var item = CartItems.NewByType(type);
serializer.Populate(obj.CreateReader(), item);
return item;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
}
}
The resulting JSON is as follows:
[{"t":1,"i":1,"n":4,"r":false,"c":[{"t":5,"i":2,"n":4,"r":false,"c":[]}]},{"t":1,"i":3,"n":4,"r":false,"c":[{"t":5,"i":4,"n":4,"r":false,"c":[{"t":4,"i":6,"n":14,"r":false,"c":[]}]},{"t":1,"i":5,"n":15,"r":false,"c":[]}]}]
And what I am trying to do, would be similar to this:
public class CartItems : List<CartItem>{
public new CartItem Add(CartItem item)
{
item.Parent = this;
base.Add(item);
return item;
}
So the problem being that we have established that deserialization doesn't call the standard Add/Insert methods from a List to populate a list. We know it is creating the list through reflection, but how? Can I intercept the assignment of the child class to the parent class, upon insertion, to assign it a variable in the child class from the parent class (i.e. child.Parent = this)?
I tried poking around in JSON.NET source to find the method in a collection it is using to populate (because even with reflection, it has to be adding them by invoking a method call, right?). Unless... It is doing something like this:
CartItems items = new CartItems() { new GenericItem() { }, new GenericItem() { } };
Edit: CartItems is the class derived from list. It is populated with multiple instances of CartItem.