2016-02-11 5 views
2

У меня возникли проблемы с десериализацией объекта JSON для класса (с использованием JSON.NET) и надеюсь, что кто-то сможет указать мне в правильном направлении. Ниже приведен фрагмент кода, который я пытаюсь, и протестировали на dotnetfiddleDeserialize JSON Object в класс

Вот образец JSON:

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

Я пытаюсь использовать этот код:

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; } 
} 

Есть ли причина, почему десериализация в класс не работает? Я просто неправильно определяю классы?

+0

Ваш, потому что они не являются тем же десериализацией? ('Словарь <строка, словарь >>' против наличия классов вместо строк (где ваш JSON не соответствует этому). – crashmstr

+0

Похоже, что ваш второй пример (тот, который не работает) вложен на один уровень глубже В вашем первом примере, будет ли он работать, если вы deserialize в качестве словаря > вместо словаря >? –

ответ

3

Здесь я вижу две проблемы: один использует классы в качестве словарных ключей - у JSON есть простые строки (и не может быть ничего действительно на самом деле), так что это не сработает.

Вторая проблема заключается в том, что десериализации JSON для классов работает путем сопоставления клавиш со свойствами - так он преобразует что-то вроде

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

к экземпляру:

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

В вашем случае это не может потому что в вашем JSON все ключи не являются допустимыми именами свойств. Вы должны придерживаться десериализации в словаре

+0

Ahh, вот что я не понимал. Спасибо за разъяснение – jared

1

Одним из способов генерации классов из JSON является использование Visual Studio.

Перейти к Edit -> Paste Special -> Paste JSON As Classes. Для опубликованных JSON, создаются следующие классы.

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; } 
} 
+0

one up .. . Чтобы показать, как повысить производительность, вставив JSON в качестве классов. –

+1

В качестве примечания стороны: Вставить JSON As Classes видна только в том случае, если вы редактируете файл кода. См. этот ответ: http://stackoverflow.com/a/18527793/ 642579 – Markus

+1

В то время как вставка как класс велика, она, похоже, не имеет никакого значения для этого вопроса, поскольку кажется, что «имена» являются переменными и фиксированными имя класса и свойства. – crashmstr

0

В дополнение к ответу Mimo, вы можете использовать ContractResolver для сериализации/десериализации словарей в рамках классов.

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

Примечание сериализованные Json с контрактного распознаватель отличается от оригинального JSON. Он должен быть сериализован с использованием этого разрешителя контракта для десериализации с ним.

Я вытащил контрактный преобразователь от this StackOverflow question, если вам нужно больше разъяснений.