0
votes

I have a type, Person, that contains an array of additional Persons:

public class Person {
  public String FirstName { get; set; }
  public String LastName { get; set; }
  public int Age { get; set; }
  public List<Person> Children { get; internal set; }

  public Person(Person parent)
  {
    if (parent != null) {
      this.LastName = parent.LastName;
    }
  }
}

I want to deserialize this from JSON using the NewtonSoft library.

{
    FirstName: "George",
    LastName: "Jetson",
    Age: 37,
    Children: [{
        FirstName: "Elroy",
        Age: 7
    }]
}

Elroy's last name should be inherited from that outer object. I deserialize this like this:

var jetsons = JsonConvert.Deserialize<Person>(json);

but the constructor for Elroy gets a null passed to it and therefore doesn't get his last name set.

How can I get the deserializer to pass the parent object as an argument to children's constructor?

1
Q: What have you tried? Could you show us the C#/Json.Net code? What happens when you execute it? Does the documentation or any of the code samples help?paulsm4

1 Answers

3
votes

Just change your Person class as

public class Person
{
    public String FirstName { get; set; }
    public String LastName { get; set; }
    public int Age { get; set; }
    public List<Person> Children { get; set; } //<== public setter
} 

and deserialize as

var person = JsonConvert.DeserializeObject<Person>(json);

That is all...

PS: Of course I assume you use a valid json. (like FirstName: "George" instead of FirstName: George)

EDIT: As mentioned by @Preston-Guillot, setting LastName to its parent's lastname is your business rule and has nothing to do with the deserialization of your json.

You can rearrange LastNames after deserialization with a recursive code as follows:

var person = JsonConvert.DeserializeObject<Person>(json);

string currLastName = null;
Action<Person> setLastNames = null;
setLastNames = p => {
    currLastName = p.LastName;
    if (p.Children != null) p.Children.ForEach(c => { if (c.LastName == null)  c.LastName = currLastName; });
    if (p.Children != null) p.Children.ForEach(c => setLastNames(c));
};
setLastNames(person);