Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JSON to C# -- list fields without sub-field names in json?

Using Json.net (Newtonsoft.json), how can I define a C# class (or classes) to handle the json below?

The 'data' field appears to be a list of level/description sub-fields but note they are not preceded by field names.

The 'error' field appears to be a list of error-number/error-message sub-fields but note, they too, are not preceded by field names.

{
  "status": "error",
  "data": [
    {
       "warning" : "your input was wrong"
    }
  ],
  "error": [
    {
      "373": "Error description goes here"
    }
  ]
}

This class definition does not generate parsing errors; however the contents of Data and Errors is not correct.

public class ApiResponse
{
    [JsonProperty(PropertyName = "status")]
    public string Status;

    [JsonProperty(PropertyName = "data")]
    public IEnumerable<KeyValuePair<string, string>> Data;

    [JsonProperty(PropertyName = "error")]
    public IEnumerable<KeyValuePair<int, string>> Errors;
};

// this doesn't throw a parsing exception, but the resulting
// Data and Errors fields are not correctly populated.
var x = JsonConvert.DeserializeObject<ApiResponse>(SampleJson);

Any help would be appreciated, thanks.

like image 535
Tony Avatar asked Oct 19 '22 07:10

Tony


1 Answers

Try defining your Data and Errors members as IEnumerables of Dictionaries rather than IEnumerables of KeyValuePairs. (Json.Net expects KeyValuePairs to be represented in JSON as objects with explicit Key and Value properties, which is not what you have there.)

public class ApiResponse
{
    [JsonProperty(PropertyName = "status")]
    public string Status;

    [JsonProperty(PropertyName = "data")]
    public IEnumerable<Dictionary<string, string>> Data;

    [JsonProperty(PropertyName = "error")]
    public IEnumerable<Dictionary<int, string>> Errors;
};

You can then read the data out using a foreach loop with SelectMany:

var x = JsonConvert.DeserializeObject<ApiResponse>(SampleJson);
foreach (var kvp in x.Data.SelectMany(d => d))
{
    Console.WriteLine(kvp.Key + ": " + kvp.Value);
}
foreach (var kvp in x.Errors.SelectMany(d => d))
{
    Console.WriteLine(kvp.Key + ": " + kvp.Value);
}

Fiddle: https://dotnetfiddle.net/KJuAPu

like image 165
Brian Rogers Avatar answered Nov 02 '22 07:11

Brian Rogers