2

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?

jared
  • 1,344
  • 4
  • 20
  • 38
  • Your because they are not the same deserialization? (`Dictionary>>` vs. having classes in place of the strings (where your JSON does not match that). – crashmstr Feb 11 '16 at 19:00
  • Looks like your second example (the one that doesn't work) is nested one level deeper. In your first example, would it work if you deserialize as Dictionary> instead of Dictionary>? – T. Yates Feb 11 '16 at 19:05

3 Answers3

3

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

MiMo
  • 11,793
  • 1
  • 33
  • 48
1

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; }
}
Abhinav Galodha
  • 9,293
  • 2
  • 31
  • 41
  • one up...for showing how to improve productivity by pasting JSON as classes. – Markus Safar Feb 11 '16 at 19:09
  • 1
    As a side note: Paste JSON As Classes is only visible if you are editing a code file. See this answer: http://stackoverflow.com/a/18527793/642579 – Markus Feb 11 '16 at 19:09
  • 1
    While paste as classes is great, it does not seem to be of any value for this question since it seems like the "names" are variable vs. a fixed class name and properties. – crashmstr Feb 11 '16 at 19:11
  • Thanks for the tip. I've normally used online tools like json2charp.com, didn't realize you can do that directly in VS. – jared Feb 11 '16 at 20:48
0

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.

Community
  • 1
  • 1