1

I am trying to parse JSON data in the following format, but I'm not sure how to set up my class.

I would like to parse this data into an IEnumerable, but I'm not sure how to reference the properties without object nodes.

[
 {
  "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,
  ...SNIP...
  "oct":1937,
  "nov":1938
   }
]

Any suggestions are greatly appreciated.

2 Answers 2

2

You're just going to have to bite the bullet here, but the good news is you'll have a result that looks like this:

Data structure

void Main()
{
    var response = JsonConvert.DeserializeObject<Response[]>(json); 
    var sorted = response.Select(x => new Year 
    {
        YearNumber = x.Year,
        Month = new Months 
        {
            Apr = x.Apr,
            Aug = x.Aug,
            Dec = x.Dec,
            Feb = x.Feb,
            Jan = x.Jan,
            Jul = x.Jul,
            Jun = x.Jun,
            Mar = x.Mar,
            May = x.May,
            Nov = x.Nov,
            Oct = x.Oct,
            Sep = x.Sep
        }
    });

    sorted.Dump();
}

public class Year
{
    public int YearNumber { get; set; }
    public Months Month { get; set; }
}

public class Months
{
    public int Jan { get; set; }
    public int Feb { get; set; }
    public int Mar { get; set; }
    public int Apr { get; set; }
    public int May { get; set; }
    public int Jun { get; set; }
    public int Jul { get; set; }
    public int Aug { get; set; }
    public int Sep { get; set; }
    public int Oct { get; set; }
    public int Nov { get; set; }
    public int Dec { get; set; }
}

public class Response
{
    [JsonProperty("year")]
    public int Year { get; set; }

    [JsonProperty("jan")]
    public int Jan { get; set; }

    [JsonProperty("feb")]
    public int Feb { get; set; }

    [JsonProperty("mar")]
    public int Mar { get; set; }

    [JsonProperty("apr")]
    public int Apr { get; set; }

    [JsonProperty("may")]
    public int May { get; set; }

    [JsonProperty("jun")]
    public int Jun { get; set; }

    [JsonProperty("jul")]
    public int Jul { get; set; }

    [JsonProperty("aug")]
    public int Aug { get; set; }

    [JsonProperty("sep")]
    public int Sep { get; set; }

    [JsonProperty("oct")]
    public int Oct { get; set; }

    [JsonProperty("nov")]
    public int Nov { get; set; }

    [JsonProperty("dec")]
    public int Dec { get; set; }
}

const 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
}]";
Sign up to request clarification or add additional context in comments.

Comments

1

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
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.