简体   繁体   中英

Json.NET C#: JToken.Parent is always null

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.

Quoting this answer:

It is not possible to get access to a parent, because parent objects are always created after their children. That is you need to read the json that the object consists of to the end to be able fully construct the object and by the time you've read the last bracket of an object, you've already read all its children. When a child parsed there is no parent yet to get the reference of.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM