Toxicable
Toxicable

Reputation: 1709

cant figure out how to map this json into C# classes

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

Upvotes: 0

Views: 264

Answers (1)

rene
rene

Reputation: 42494

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.

Upvotes: 1

Related Questions