jared
jared

Reputation: 1364

Deserialize JSON Object into Class

I'm having a little trouble deserializing a JSON object to a class (using JSON.NET), and hoping someone can point me in the right direction. Below is a snippet of code I'm trying, and been testing at dotnetfiddle

Here's a sample of the JSON:

{
    "`LCA0001": {
        "23225007190002": "1",
        "23249206670003": "1",
        "01365100070018": "5"
    },
    "`LCA0003": {
        "23331406670018": "1",
        "24942506670004": "1"
    },
    "`LCA0005": {
        "01365100070018": "19"
    }
}

I'm trying to use this code:

using System;
using System.Collections.Generic;
using Newtonsoft.Json;

public class Program
{
    public static void Main()
    {

        string json = "{\"`LCA0001\": {\"23225007190002\": \"1\",\"23249206670003\": \"1\",\"01365100070018\": \"5\"},\"`LCA0003\": {\"23331406670018\": \"1\",\"24942506670004\": \"1\"},\"`LCA0005\": {\"01365100070018\": \"19\"}}";
        Console.WriteLine(json);
        Console.WriteLine();

        //This works
        Console.Write("Deserialize without class");
        var root = JsonConvert.DeserializeObject<Dictionary<string, Dictionary<string, int>>>(json);
        foreach (var locationKvp in root)
        {
            foreach (var skuKvp in locationKvp.Value)
            {
                Console.WriteLine("location: " + locationKvp.Key + ", sku: " +  skuKvp.Key + ", qty: " + skuKvp.Value);
            }
        }

        //Why doesn't this work?
        Console.Write("\nDeserialize with class");      
        var root2 = JsonConvert.DeserializeObject<InventoryLocations>(json);
        foreach (var locationKvp in root2.InventoryLocation)
        {
            foreach (var skuKvp in locationKvp.Value)
            {
                Console.WriteLine("location: " + locationKvp.Key + ", sku: " +  skuKvp.Key + ", qty: " + skuKvp.Value);
            }
        }
    }
}

class InventoryLocations
{
    public Dictionary<Location, Dictionary<Sku, Qty>> InventoryLocation { get; set; }
}

public class Location
{
    public string location { get; set; }
}

public class Sku
{
    public string sku { get; set; }
}

public class Qty
{
    public int qty { get; set; }
}

Is there a reason why deserializing into a Class doesn't work? Am I just defining the classes incorrectly?

Upvotes: 2

Views: 1670

Answers (3)

Rod-Serling
Rod-Serling

Reputation: 1

In addition to MiMo's answer, you can use a ContractResolver to serialize/deserialize Dictionaries within classes.

Here's a working example of your code in dotnetfiddle.

Note the serialized Json with the contract resolver is different than the original json. It must be serialized using this contract resolver in order to deserialize with it as well.

I pulled the contract resolver from this StackOverflow question, if you need any more clarification.

Upvotes: 0

Abhinav Galodha
Abhinav Galodha

Reputation: 9878

One of the ways to generate the classes from JSON is using Visual Studio.

Navigate to Edit -> Paste Special -> Paste JSON As Classes. For posted JSON in question, following classes are generated.

public class Rootobject
{
    public LCA0001 LCA0001 { get; set; }
    public LCA0003 LCA0003 { get; set; }
    public LCA0005 LCA0005 { get; set; }
}

public class LCA0001
{
    public string _23225007190002 { get; set; }
    public string _23249206670003 { get; set; }
    public string _01365100070018 { get; set; }
}

public class LCA0003
{
    public string _23331406670018 { get; set; }
    public string _24942506670004 { get; set; }
}

public class LCA0005
{
    public string _01365100070018 { get; set; }
}

Upvotes: 1

MiMo
MiMo

Reputation: 11953

I see two problems here: one is using classes as the dictionary keys - the JSON has simple strings there (and cannot have anything else really), so that won't work.

The second problem is that deserialization of JSON to classes works by matching keys to properties - so it converts something like

{
    "prop1": "value1",
    "prop2": "value2"
}

to an instance of:

public class MyClass {
   public string prop1 { get; set; }
   public string prop2 { get; set; }
}

In your case this cannot work because in your JSON all keys are not valid property names. You have to stick with the deserialization to a dictionary

Upvotes: 3

Related Questions