简体   繁体   中英

Json.net deserialize “flat” json data

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.

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:

数据结构

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
}]";

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

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