I'm working on a Json.NET serialisation system that relies heavily on custom converters, contract resolver, and attributes. The system aims to handle reference deserialisation, including mutual referencing and resolving that isn't order-sensitive. I'm not using Json.NET's native system for this because we have special requirements.
My current system identifies the request for a reference when an object is being deserialised. This reference takes the form of either a numeric ID, or a human-legible string. If the reference's requested object has already been deserialised, then the object in need of the reference is simply assigned its correct value from a large dictionary. If it is not, a "reference request" is submitted. This request contains an object, and an ID.
When I wrote this system, I didn't realise that changing the object in the reference request would not automatically change its recipient. Thus, it simply doesn't work.
However, solving this should be quite simple. If I get an object's encapsulating field-owner (if, for example, Wine is defined within Dinner, I need to retrieve Dinner when examining Wine during deserialisation), I can simply use reflection to set the field. I'm essentially storing the field address. And from what I gather, this should be perfectly possible by traversing the Json hierarchy via JToken.Parent
. However, when I try and access this field in an object that should have a parent, it's null. I've searched and searched, but I've found no indication that Parent
is something I need to set myself; I assumed it was handled internally by Json.NET. Why is this null?
Below is an example. FoodExample contains a field of Food, which itself defines a field of Wine.
public class FoodExample
{
// This meal contains a defined instance of Wine, instead of a reference.
public Food definedMeal = null;
public FoodExample()
{
}
public void Initialise()
{
Food definedMeal = new Food("Steak", new Wine("Pinot Noir", 15.99f));
}
}
When deserialising Wine using my custom converter, I query the Wine's JToken.Parent
field, like so:
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Debug.Log("Deserialising definition: " + objectType);
// Create a JObject. Use it to get a JReader,
JObject jObject = JObject.Load(reader);
JsonReader jsonReader = jObject.CreateReader();
Debug.Log("Parent: " + (jObject.Parent == null)); // Prints true
}
Json output:
{
"definedMeal": {
"ID": 1,
"name": "Steak",
"pairsWellWith": {
"ID": 0,
"price": 15.99,
"name": "Pinot Noir"
}
}
}
The parent for both objects in this hierarchy appear as null when being passed through my custom converter.
It's probably worth mentioning that I'm working in Unity3D.