Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Json deserialization with different variable names (FIXED Posted Solution)

Hello I'm working on a windows form application to enter in Magic The Gathering cards I have into a database for easy organization. In order to enter the card data fast I plan on using the MTG master card Json file which contains every card made and all of it's attributes. But the way they have the Json file doesn't seem to work well with the deserialization in Visual C#.

Here is what two entries look like:

{
"Air Elemental":{
(stuff that doesn't matter for the question)
},
"Ancestral Recall":{
. . .
}
}

As you can see the variable name for the data is different for every single one which is where the problem lies. I can't get C# to deserialize it correctly into a class because it wants the JsonProperty name and because it is different I can't really set it.

So if there is a way to specify that it doesn't need to have a specific name and it just stores what's placed in that variable I would really appreciate if you could tell me.

Thank you for any help you can provide.

SOLUTION

Thanks to Henrik I found out how to fix this problem. Here is what he posted:

dynamic data = JsonConvert.DeserializeObject(responseData);
IDictionary<string, JToken> cards = data;

foreach (var card in cards)
{
    var key = card.Key;
    var value = card.Value;
}

Which wasn't fully what I had to do but it laid out the ground of the solution. I figured out that the card.Value actually held all the Json text of the card so all I needed to do was use Json.DeserializeObject one more time but this time into my class that has all the values set to variables. Here's what it looks like

string json;
using (StreamReader sr = new StreamReader("G:/MTG Card Database/Files/AllCardsShort.json"))
{
    json = sr.ReadToEnd();
    sr.Close();
}

dynamic data = JsonConvert.DeserializeObject(json);
IDictionary<string, JToken> cards = data;

foreach (var card in cards)
{
   CardData newCard = JsonConvert.DeserializeObject<CardData>(card.Value.ToString());
   textBox1.Text = newCard.name; //Check to see if the name can be put into a textbox
   break;
}
. . . 
public class CardData
{
    [JsonProperty("layout")]
    public string layout { get; set; }
    [JsonProperty("name")]
    public string name { get; set; }
    [JsonProperty("manaCost")]
    public string manaCost { get; set; }
    [JsonProperty("cmc")]
    public string cmc { get; set; }
    [JsonProperty("colors")]
    public string[] colors { get; set; }
    [JsonProperty("type")]
    public string type { get; set; }
    [JsonProperty("subtypes")]
    public string[] subTypes { get; set; }
    [JsonProperty("text")]
    public string text { get; set; }
    [JsonProperty("power")]
    public string power { get; set; }
    [JsonProperty("toughness")]
    public string toughness { get; set; }
    [JsonProperty("imageName")]
    public string imageName { get; set; }
}

So again thank you Henrik for helping out. And thank you to everyone else that posted their idea as well!

like image 800
nickqqqq1 Avatar asked May 16 '15 04:05

nickqqqq1


1 Answers

Using Json.NET:

dynamic data = JsonConvert.DeserializeObject(responseData);
IDictionary<string, JToken> cards = data;

foreach (var card in cards)
{
    var key = card.Key;
    var value = card.Value;
}
like image 147
Henrik Avatar answered Nov 05 '22 11:11

Henrik