1

I'm fairly new to json, and I'm trying to convert some json content to a C# class to store it for later use. I'm having a problem trying to create a class which is suitable for the data structure. An example of the json content is shown below.

Json Data

{
 "FirstItem": {
 "id": 1,
 "type": "foo",
 "colours": ["blue", "black", "green"],
 "reviews": {
 "positive": ["The best", "unbelievable", "Awesome"],
 "negative": ["Sh*t", "Awful", "Dire", "Terrible", "Appalling"],
 "neutral": ["OK", "Meh"]
 }
 },
 "SecondItem": {
 "id": 2,
 "type": "bar",
 "colours": ["red", "white", "yellow"],
 "reviews": {
 "positive": ["Great", "Amazing", "Fantastic", "Perfect", "Uplifting"],
 "negative": ["Terrible", "Shocking", "abysmal"],
 "neutral": ["OK", "Standard", "Vanilla"]
 }
 }
}

Edit:

It's worth noting that this is just a small sample of the json data, and I expect to be working with a much larger data set which is always in this format, however the FirstItem, SecondItem (names?) will always be different. I could potentially end up with a MillionthItem.

C# Class

I have created a class based on my limited understanding of the json data above. I think this is where the problem lies - I dont think this class is suitable based on the json above. Here's what I have.

public class Data
{
 public string name {get; set;}
 public int id {get; set;}
 public string type {get; set;}
 public string[] colours {get; set;}
 public Reviews reviews {get; set;}
}
public class Reviews
{
 public string[] positive {get; set;}
 public string[] negative {get; set;}
 public string[] neutral {get; set;}
}

Converting json to class

To try and convert this, I am using JsonConvert to deserialize the data to a List of a class which I have created. For example:

var client = new RestClient(url);
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
var result = JsonConvert.DeserializeObject<List<Data>>(response.Content);

Exception

Cannot deserialize the current JSON object (e.g. {"name":"value"}) into type 'System.Collections.Generic.List`1[namespace.class]' because the type requires a JSON array (e.g. [1,2,3]) to deserialize correctly. To fix this error either change the JSON to a JSON array (e.g. [1,2,3]) or change the deserialized type so that it is a normal .NET type (e.g. not a primitive type like integer, not a collection type like an array or List) that can be deserialized from a JSON object. JsonObjectAttribute can also be added to the type to force it to deserialize from a JSON object.

Summary

I'd appreciate some advice on understanding the json format above, and how I can successfuly convert this

Solution

dbc suggested storing this information in a dictionary, which was exactly what I was needing to do - this allows me to capture the name (FirstItem, SecondItem etc.) as the key and the rest of the class Data as the value.

var result = JsonConvert.DeserializeObject<Dictionary<string, Data>>(response.Content);
asked Mar 18, 2018 at 16:22
4
  • Have you tried using a Json to poco converter? There's a few online ones that sometimes do a good job. Commented Mar 18, 2018 at 16:26
  • Are "FirstItem", "SecondItem" and so on variable and not fixed? If so then use a dictionary: var result = JsonConvert.DeserializeObject<Dictionary<string, Data>>(response.Content); Commented Mar 18, 2018 at 16:34
  • See for instance How can I parse a JSON string that would cause illegal C# identifiers? or Create a strongly typed c# object from json object with ID as the name for pre-existing questions. Commented Mar 18, 2018 at 16:40
  • @dbc, this is exactly what I was needing. This allows me to capture the 'name' (FirstItem etc.) and the data for each record that is returned from the API call. Thanks muchly! Commented Mar 18, 2018 at 16:45

1 Answer 1

7

Just copy your json and do Edit->Paste Special->Paste Json As Classes in Visual Studio - it will create you the matching class structure.

 public class Rootobject
 {
 public Firstitem FirstItem { get; set; }
 public Seconditem SecondItem { get; set; }
 }
 public class Firstitem
 {
 public int id { get; set; }
 public string type { get; set; }
 public string[] colours { get; set; }
 public Reviews reviews { get; set; }
 }
 public class Reviews
 {
 public string[] positive { get; set; }
 public string[] negative { get; set; }
 public string[] neutral { get; set; }
 }
 public class Seconditem
 {
 public int id { get; set; }
 public string type { get; set; }
 public string[] colours { get; set; }
 public Reviews1 reviews { get; set; }
 }
 public class Reviews1
 {
 public string[] positive { get; set; }
 public string[] negative { get; set; }
 public string[] neutral { get; set; }
 }

Then usage will be like:

 var rootObject = JsonConvert.DeserializeObject<Rootobject>(jsonString);
answered Mar 18, 2018 at 16:28
2
  • I never knew this existed, thanks for pointing this out! The probelm with using this is that a class would have to exist for every item, and I expect much more than just FirstItem & SecondItem. I've updated my post to reflect this. Commented Mar 18, 2018 at 16:39
  • 1
    It's no problem, but your Json structure is incorrect then - you are really looking for array of Items, so your json should start with [ and end with ]. If you can change the structure then you could add JsonArray attribute to FirstItem class and deserialize directly into a List<FirstItem> (should probably rename the class then as well to Item) Commented Mar 18, 2018 at 16:43

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.