序列化JSON并省略Geckoboard trendline小部件的属性名称

时间:2016-01-11 17:31:05

标签: c# json serialization json.net

尝试为geckoboard小部件生成以下JSON(trendline

{
"item": [
    {
      "value": "274057"
    },
    [
      "38594",
      "39957",
      "35316",
      "35913",
      "36668",
      "45660",
      "41949"
    ]
  ]
}

这是我的模特:

    public class NumberAndSecondaryStat
    {
        [JsonProperty("item")]
        public DataItem[] DataItems { get; set; }

         [JsonProperty("")]
        public List<string> TrendData { get; set; }
    }

    public class DataItem
    {
        [JsonProperty("value")]
        public decimal? Value { get; set; }
    }

生成的JSON存在一些问题,但我最大的问题是让属性名称消失。

我生成的JSON:

"item": [
  {        
    "value": 223.0
  }
],
"": [
  "100",
  "102",
  "105",
  "109"
]

这里完全相同的问题:C# class for specific JSON / Geckoboard / Trendline widget。只是不确定自定义序列化程序规则应该是什么样的。

1 个答案:

答案 0 :(得分:1)

由于您的"items" JSON数组极其多态,由对象和嵌套数组组成,因此最简单的方法是使用自定义JsonConverter来重写与JSON之间的c#数据模型:

public class NumberAndSecondaryStatConverter : JsonConverter
{
    public override bool CanConvert(Type objectType)
    {
        return objectType == typeof(NumberAndSecondaryStat);
    }

    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        if (reader.TokenType == JsonToken.Null)
            return null;
        var token = JToken.Load(reader).SelectToken("item");
        if (token == null)
            return null;
        var value = (existingValue as NumberAndSecondaryStat) ?? new NumberAndSecondaryStat();
        value.DataItems = token.OfType<JObject>().Select(o => o.ToObject<DataItem>()).ToArray();
        value.TrendData = token.OfType<JArray>().SelectMany(a => a.Select(i => (string)i)).ToList();
        return value;
    }

    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        var stat = (NumberAndSecondaryStat)value;
        serializer.Serialize(writer, new { item = (stat.DataItems ?? Enumerable.Empty<object>()).Concat(new[] { stat.TrendData ?? Enumerable.Empty<string>() }) });
    }
}

然后您可以按如下方式应用它:

[JsonConverter(typeof(NumberAndSecondaryStatConverter))]
public class NumberAndSecondaryStat
{
    public DataItem[] DataItems { get; set; }

    public List<string> TrendData { get; set; }
}