0

So I have the json below that I want to Deseralize into Classes so I can work with it. But the issues is that the top two fields are a different type to all the rest

"items": {
    "averageItemLevel": 718,
    "averageItemLevelEquipped": 716,
    "head": { ... },
    "chest": { ... },
    "feet": { ... },
    "hands": { ... }
    }

Where ... is a the Item class below, but the problem is that 2 of the fields are ints and the rest are Item, there are about 20 fields in total. So what I'd like to do is put them into a Dictionary<string, Item> but the 2 int fields are preventing me from Deseralizing it into that. I'm using JavaScriptSerializer.Deserialize<T>() to do this.

I could have each item as it's own class with the name of the item as the name of the class, but I find that to be very bad, repeating so much each time, also very hard to work with later since I cant iterate over the fields, where as I could a Dictionary. Any idea how I could overcome this?

public class Item
{
    public ItemDetails itemDetails { get; set; }
    public int id { get; set; }
    public string name { get; set; }
    public string icon { get; set; }
    public int quality { get; set; }
    public int itemLevel { get; set; }
    public TooltipParams tooltipParams { get; set; }
    public List<Stat> stats { get; set; }
    public int armor { get; set; }
    public string context { get; set; }
    public List<int> bonusLists { get; set; }
}

Update: from the comments I came up with this solution

JObject jsonObject = JObject.Parse(json);

jsonObject["averageItemLevel"] = int.Parse(jsonObject["items"]["averageItemLevel"].ToString());
jsonObject["averageItemLevelEquipped"] = int.Parse(jsonObject["items"]["averageItemLevelEquipped"].ToString());
jsonObject["items"]["averageItemLevel"].Parent.Remove();
jsonObject["items"]["averageItemLevelEquipped"].Parent.Remove();

var finalJson = jsonObject.ToString(Newtonsoft.Json.Formatting.None);
var character = _serializer.Deserialize<Character>(finalJson);
character.progression.raids.RemoveAll(x => x.name != "My House");

return character
Toxicable
  • 1,639
  • 2
  • 21
  • 29
  • If you are going down the classes route, there are tools available that you just paste in the json and it generates the classes for you. here is one such tool: http://jsonutils.com/ – Nkosi Apr 10 '16 at 03:38
  • @Nkosi yeah i'm aware of these kinda of tools, as great as they are they will simply make a class for each `Item` as I mentioned which makes it rather messy and hard to work with the data – Toxicable Apr 10 '16 at 03:40
  • Ok I understand. You could try `Dictionary` and see if it will parse the other complex objects as dictionaries as well – Nkosi Apr 10 '16 at 03:41
  • 1
    The following answer works with Json.net and deserializes the json to `IDictionary` http://stackoverflow.com/a/20728229/5233410 – Nkosi Apr 10 '16 at 03:53
  • @Nkosi Hey, that's an idea. Parse it all into `objects`, which `int` is, then I'll move the `int` entries and reparse the other ones into items – Toxicable Apr 10 '16 at 03:57
  • @Nkosi So from what you suggested I ended up with the solution above, not sure how efficient it is but I guess it'll do now untill I think of something better. – Toxicable Apr 10 '16 at 04:32

1 Answers1

1

If I add these two classes to match your JSON I can serialize and deserialize the objects:

public class root
{
    public Items items { get; set; }
}

public class Items
{
    public int averageItemLevel { get; set; }
    public int averageItemLevelEquipped { get; set; }
    public Item head {get;set;}
    public Item chest {get;set;}
    public Item feet {get;set;}
    public Item hands {get;set;}
}

Test rig with the WCF Serializer:

var obj = new root();
obj.items = new Items
{
    averageItemLevel = 42,
    feet = new Item { armor = 4242 },
    chest = new Item { name = "super chest" }
};

var ser = new DataContractJsonSerializer(typeof(root));

using (var ms = new MemoryStream())
{
    ser.WriteObject(ms, obj);

    Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
    Console.WriteLine("and deserialize");

    ms.Position = 0;
    var deserializeObject = (root) ser.ReadObject(ms);

    Console.WriteLine(deserializeObject.items.feet.armor);
}

And with the JavaScriptSerializer:

var jsser = new JavaScriptSerializer();
var json = jsser.Serialize(obj);

Console.WriteLine(json);
Console.WriteLine("and deserialize");

var djson = jsser.Deserialize<root>(json);

Console.WriteLine(djson.items.feet.armor);

Both serializers give the same result for your given JSON.

rene
  • 41,474
  • 78
  • 114
  • 152