Deserialize nested YAML using YamlDotNEt and custom type class in c#

2.5k views Asked by At

I have been going around this for a few days and just can't get this working. I have a YAML file that follows the following format (Note I can't change the delivery format as it's external). I have picked a random topic but the structure is the same.

gender: male
age: 21
eyes: blue
lastLogins:
- 12/12/2016
- 14/12/2016
- 15/12/2016
addresses:
   po011aa:
      streetAddress: 1 the road
      phoneNumber: 0118123123456
   po21bb:
      streetAddress: 1 another road
      phoneNunder: 012345643556
hasPets: true

I have created a custom class to contain this data when Deserialized.

Something like:

public class person
{
public string gender {get; set;}
public string age {get; set;}
public string eyes {get; set;}
public List<string> lastLogins {get; set;}
public addressList addresses {get; set;}
public string hasPets {get; set;}
}

public class addressList
{
public List<addressData> **QUESTION1** {get; set;}
}

public class addressData
{
public string postCost {get; set;} **QUESTION2**
public string streetAddress {get; set;}
public string phoneNumber {get; set;}
}

SO!

Question1: What name can I use, or how can I, have the addressData list accept any name. Basically accept it because of where it is in the structure rather than by the name of key.

Question2: I want to record the key name from the 'container' of this addressData and save that into the postcode spot of the addressData object.

1

There are 1 answers

0
Antoine Aubry On BEST ANSWER

As @flyx mentioned, you should use a class that implements IDictionary<,> to deserialize the addresses field since is is a mapping. The simplest solution is to remove the addressList class and use Dictionary<string, addressData> instead.

public class person
{
    public string gender {get; set;}
    public string age {get; set;}
    public string eyes {get; set;}
    public List<string> lastLogins {get; set;}
    public Dictionary<string, addressData> addresses {get; set;}
    public string hasPets {get; set;}
}

public class addressData
{
    public string postCost {get; set;}
    public string streetAddress {get; set;}
    public string phoneNumber {get; set;}
}

Alternatively, you can make addressList implement IDictionary<string, addressData>, but that would be more work.

The hasPets property should probably be a bool instead of a string.

Also, you might want to specify a naming convention so that your classes can follow the standard .NET conventions:

var deserializer = new DeserializerBuilder()
    .WithNamingConvention(new CamelCaseNamingConvention())
    .Build();