Reputation: 369
Okay, so I'm working on creating a REST-API, and in order to seed my database I use existing data in the forms of huge JSON-files. And I have a problem when it comes to deserializing one of the fields.
So the JSON looks like this:
{
"name" : "Magic 2013",
"booster" : [
"land",
"marketing",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"common",
"uncommon",
"uncommon",
"uncommon",
[
"rare",
"mythic rare"
]
]
}
And when you look at this, you can probably identify the problem as well. There's a field called booster, which is an array of strings.. but the last element is not a string. It's another array. So trying to deserialize it to a string[]-field fails.
I have to work with this format - there's no way for me to change it, so I'm going to have to figure out a smart way to solve this problem. Which is what I need help with.
Are there any way with JSON.NET that i could actually deserialize this? Some way I could do some sort of manual mapping saying that whenever I reach the inner array, I'm going to do some custom code?
I would be grateful for any help!
Thanks!
Upvotes: 1
Views: 80
Reputation: 1039140
You could define the booster
property as JArray
:
public JArray Booster { get; set; }
This doesn't enforce a specific data type of the array. You can then loop through each element of this array (which will be a JToken
) and test if it is a string value or yet another JArray
and act accordingly:
foreach (JToken token in model.Booster)
{
var array = token as JArray();
if (array != null)
{
// The element is an array, so you can process its subelements here
}
else
{
// It's probably a string element
string value = token.ToObject<string>();
}
}
Upvotes: 3
Reputation: 4178
If it will always be the last element that will have the array instead of a string, you can deserializer is using
public class RootObject
{
public string name { get; set; }
public List<object> booster { get; set; }
}
and then extract element of the booster
List using
var oddItem = booster[booster.Count -1];
This is assuming that its always the last element which is an array
Upvotes: 0
Reputation: 27105
So this works for me:
class WhateverMyThingIsNamed
{
public string Name { get; set; }
public object[] Booster { get; set; }
public IEnumerable<string> GetBooster()
{
foreach (var o in Booster)
{
if (o is string)
{
yield return (string) o;
}
else if (o is JArray)
{
foreach (var element in (JArray) o)
{
yield return element.Value<string>();
}
}
else
{
throw new InvalidOperationException("Unexpected element");
}
}
}
}
...
var json = File.ReadAllText("json1.json");
var data = new JsonSerializer().Deserialize<WhateverMyThingIsNamed>(new JsonTextReader(new StringReader(json)));
var boosterList = data.GetBooster().ToList();
Upvotes: 0