简体   繁体   中英

How to have JSON.NET render forward references during serialization

JSON.NET (using the setting PreserveReferencesHandling = PreserveReferencesHandling.Objects ) serializes a reoccurring object inline on first occurrence and serialzes it as JSON reference on subsequent occurrences. I'm guessing this is done to avoid forward references.

For example:

class Person
{
    public string Name { get; set; }
    public Person Mother { get; set; }
}

var joni = new Person { Name = "Joni" };
var james = new Person { Name = "James", Mother = joni };

var people = new List<Person> { james, joni };

var json = JsonConvert.SerializeObject(people, Formatting.Indented,
    new JsonSerializerSettings {
       PreserveReferencesHandling = PreserveReferencesHandling.Objects });

results in the following:

[
  {
    "$id": "1",
    "Name": "James",
    "Mother": {
      "$id": "2",
      "Name": "Joni",
      "Mother": null
    }
  },
  {
    "$ref": "2"
  }
]

Instead, I'd like to get this:

[
  {
    "$id": "1",
    "Name": "James",
    "Mother": {
      "$ref": "2"
    }
  },
  {
    "$id": "2",
    "Name": "Joni",
    "Mother": null    
  }
]

Although both are effectively equal, I find the second much more sensible, especially when editing the JSON data by hand (which is a use case for me in this matter).

Is there a way of controlling which instance is serialized as a reference or am I stuck with this first-occurrence behavior?

EDIT

I've tried deserializing the desired JSON and found that JSON.NET doesn't do that properly because of the forward reference.

What is going on there is that you are instancing a Person variable inside your Person variable. So when you create the "son":

class Person
{
    public string Name { get; set; }
    public Person Mother { get; set; }
}

You are creating a Mother variable inside, that is a Person type variable, and has all the attributes that a regular Person variable would have, with the resulting JSON file you are obtaining.

Instead of doing that, you can try to create a new class "Mother" that inherits from the class "Person" and only has the ID attribute, so when you create the JSON file, you will obtain the expected result.

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