Json.net反序列化“平坦”的json数据

时间:2014-12-14 03:57:23

标签: c# json json.net

我正在尝试以下列格式解析JSON数据,但我不确定如何设置我的课程。

我想将这些数据解析为IEnumerable,但我不确定如何在没有对象节点的情况下引用这些属性。

[
 {
  "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
   }
]

非常感谢任何建议。

2 个答案:

答案 0 :(得分:2)

你只需要在这里咬紧牙关,但好消息是你有一个看起来像这样的结果:

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

答案 1 :(得分:1)

我刚刚从user3473830

Json.NET - controlling class object-properties deserialization提取的内容

我提出了这个解决方案:

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

数据类

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

自定义转换器

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