From what I just have lerned from user3473830 in Json.NET - controlling class object-properties deserialization
I came up with this solution:
Programm:
class Program
{
static void Main(string[] args)
{
var years = JsonConvert.DeserializeObject<IEnumerable<YearInfo>>(json);
}
private static string json = @"
[
{
'year':2005,
'jan':0,
'feb':0,
'mar':0,
'apr':6,
'may':93,
'jun':341,
'jul':995,
'aug':1528,
'sep':1725,
'oct':1749,
'nov':1752,
'dec':1752
},
{
'year':2006,
'oct':1937,
'nov':1938
}
]";
}
Data classes:
[JsonConverter(typeof(YearInfoConverter))]
class YearInfo
{
public YearInfo(int year)
{
Year = year;
}
[JsonIgnore]
public int Year { get; set; }
public List<MonthInfo> Months { get; set; }
}
class MonthInfo
{
public string Name { get; set; }
public int Value { get; set; }
}
Custom converter:
public class YearInfoConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
return typeof(JsonConverter) == objectType;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
var jObject = JObject.Load(reader);
var year = jObject["year"].Value<int>();
var yearInfo = existingValue ?? Activator.CreateInstance(objectType, year);
List<MonthInfo> months = new List<MonthInfo>();
foreach (var item in (jObject as IEnumerable<KeyValuePair<string, JToken>>).Skip(1))
{
months.Add(new MonthInfo()
{
Name = item.Key,
Value = item.Value.Value<int>()
});
}
objectType.GetProperty("Months").SetValue(yearInfo, months);
return yearInfo;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
//we just want to deserialize the object so we don't need it here, but the implementation would be very similar to deserialization
}
}