1

Trying to generate the following JSON for a geckoboard widget (trendline)

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

This is my model:

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

Have a couple of issues with the resulting JSON, but my biggest problem is getting the property name to disappear.

My generated JSON:

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

Exact same question here: C# class for specific JSON / Geckoboard / Trendline widget. Just not sure what the custom serializer rules should look like.

Community
  • 1
  • 1
xm1994
  • 473
  • 3
  • 11
  • You should probably remove the `geckoboad` tag as this question is not really something that someone with that kind of expertise could really help you. Might consider replacing it with a tag of `json.net` since someone who's very good with that is the attention you are looking for. – CodingGorilla Jan 11 '16 at 17:35

1 Answers1

1

Since your "items" JSON array is extremely polymorphic, consisting of both objects and nested arrays, it will be easiest to use a custom JsonConverter to rewrite your c# data model to and from JSON:

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>() }) });
    }
}

Then you can apply it as follows:

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

    public List<string> TrendData { get; set; }
}
dbc
  • 104,963
  • 20
  • 228
  • 340