Collectives™ on Stack Overflow
Find centralized, trusted content and collaborate around the technologies you use most.
Learn more about Collectives
Teams
Q&A for work
Connect and share knowledge within a single location that is structured and easy to search.
Learn more about Teams
In a Windows Phone app using C#, I am trying to deserialize some JSON with the following structure:
[ { "kite" : { "supplier" : "ABC",
"currency" : "GBP",
"cost" : "7.98"
{ "puzzle" : { "supplier" : "DEF",
"currency" : "USD",
"cost" : "7.98"
{ "ball" : { "supplier" : "DEF",
"currency" : "USD",
"cost" : "5.49"
This is a list of toys in which the names of the toys (kite, puzzle, ball) are not known in advance. I don't have any control over the format of the JSON.
Using json2csharp.com I get the following classes:
public class Kite
public string supplier { get; set; }
public string currency { get; set; }
public string cost { get; set; }
public class Puzzle
public class Ball
public class RootObject
public Kite kite { get; set; }
public Puzzle puzzle { get; set; }
public Ball ball { get; set; }
This looks to me like an array of "toy" objects but I don't know what approach to take when deserializing this.
The only code that I have had work is the basic:
var root = JsonConvert.DeserializeObject(rawJSON);
I thought something like the following might work, but I would lose the name of the toy if it worked (and it doesn't):
public class Toy
public string supplier { get; set; }
public string currency { get; set; }
public string cost { get; set; }
List<Toy> toyList = (List<Toy>) JsonConvert.DeserializeObject(rawJSON, typeof(List<Toy>));
Any suggestions please?
–
You are close. If you define your Toy
class as you have it in your question, you can deserialize into a List<Dictionary<string, Toy>>
. Thus, each toy is actually represented by a Dictionary
with a single entry in it. The Key
is the name of the toy and the Value
is the Toy
info.
Here is a demo:
string json = @"
[ { ""kite"" : { ""supplier"" : ""ABC"",
""currency"" : ""GBP"",
""cost"" : ""7.98""
{ ""puzzle"" : { ""supplier"" : ""DEF"",
""currency"" : ""USD"",
""cost"" : ""7.98""
{ ""ball"" : { ""supplier"" : ""DEF"",
""currency"" : ""USD"",
""cost"" : ""5.49""
List<Dictionary<string, Toy>> list =
JsonConvert.DeserializeObject<List<Dictionary<string, Toy>>>(json);
foreach (Dictionary<string, Toy> dict in list)
KeyValuePair<string, Toy> kvp = dict.First();
Console.WriteLine("toy: " + kvp.Key);
Console.WriteLine("supplier: " + kvp.Value.Supplier);
Console.WriteLine("cost: " + kvp.Value.Cost + " (" + kvp.Value.Currency + ")");
Console.WriteLine();
This outputs the following:
toy: kite
supplier: ABC
cost: 7.98 (GBP)
toy: puzzle
supplier: DEF
cost: 7.98 (USD)
toy: ball
supplier: DEF
cost: 5.49 (USD)
Admittedly, this solution is kind of "clunky", because it would be better to have the name of the toy included in the Toy
class itself rather than have an intervening Dictionary
to stumble over. There are two ways to fix this. One way is to add a Name
property on the Toy
class, deserialize into the same structure as shown above, then do a little bit of post-processing to move the names from each Dictionary
into the respective Toy
, building a new List<Toy>
in the process. The second way to do it is to create a custom JsonConverter
to handle this translation during deserialization. I'd be happy to demonstrate either of these alternate approaches if you wish. Just let me know. If you just need quick-and-dirty, then the above approach should do.
Alternative approach using a custom JsonConverter
This approach is a little "cleaner" because we can keep all the Toy
info together on a single strongly-typed object, and keep all the deserialization logic separate so it doesn't clutter up the main code.
First, we need to alter your Toy
class to give it a Name
property.
class Toy
public string Name { get; set; }
public string Supplier { get; set; }
public string Currency { get; set; }
public decimal Cost { get; set; }
Next, we create a class which inherits from JsonConverter
.
class ToyConverter : JsonConverter
public override bool CanConvert(Type objectType)
// This lets JSON.Net know that this converter can handle Toy objects
return (objectType == typeof(Toy));
public override object ReadJson(JsonReader reader,
Type objectType, object existingValue, JsonSerializer serializer)
// load the toy JSON object into a JObject
JObject jo = JObject.Load(reader);
// get the first (and only) property of the object
JProperty prop = jo.Properties().First();
// deserialize the value of that property (which is another
// object containing supplier and cost info) into a Toy instance
Toy toy = prop.Value.ToObject<Toy>();
// get the name of the property and add it to the newly minted toy
toy.Name = prop.Name;
return toy;
public override void WriteJson(JsonWriter writer,
object value, JsonSerializer serializer)
// If you need to serialize Toys back into JSON, then you'll need
// to implement this method. We can skip it for now.
throw new NotImplementedException();
To use the converter, we just need to create an instance of it and pass it in the call to DeserializeObject<T>()
. Now that we have this converter, we can deserialize directly into a List<Toy>
, which is much more natural.
List<Toy> toys = JsonConvert.DeserializeObject<List<Toy>>(json, new ToyConverter());
Accessing the toy data from there is straightforward.
foreach (Toy toy in toys)
Console.WriteLine("toy: " + toy.Name);
Console.WriteLine("supplier: " + toy.Supplier);
Console.WriteLine("cost: " + toy.Cost + " (" + toy.Currency + ")");
Console.WriteLine();
You'll notice this gives exactly the same output as the previous example, but the code is much cleaner.
–
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.