2014-11-17 3 views
1

У меня следующий JSON СтрокаDeserialize JSON строку в DataTable/DataSet с помощью C#

{ 
"1":[ 
     {"cityId":93,"cityName":"Tapah","cityCode":"TAP"}, 
     {"cityId":3,"cityName":"Melaka","cityCode":"MLK"}, 
     {"cityId":6,"cityName":"Kota Bharu","cityCode":"KB"}, 
     {"cityId":7,"cityName":"Dungun","cityCode":"DG"} 
    ], 
"2":[ 
     {"cityId":77,"cityName":"Grik","cityCode":"GRIK"}, 
     {"cityId":6,"cityName":"Kota Bharu","cityCode":"KB"}, 
     {"cityId":7,"cityName":"Dungun","cityCode":"DG"}, 
     {"cityId":98,"cityName":"Bangan Serai","cityCode":"BS"} 
    ], 
"6":[ 
     {"cityId":3,"cityName":"Melaka","cityCode":"MLK"}, 
     {"cityId":82,"cityName":"Teluk Intan","cityCode":"TI"}, 
     {"cityId":7,"cityName":"Dungun","cityCode":"DG"} 
    ] 
} 

Когда я с помощью Json.NET

DataSet OBJ = JsonConvert.DeserializeObject (responseBody);

Я получаю следующую таблицу только

cityId | cityName | cityCode 
----------------------------------- 
93   Tapah   TAP 
3   Melaka   MLK 
6   Kota Bharu  KB 
7   Dungun   DG 

Мне нужно нравится этот

from | cityId | cityName | cityCode 
----------------------------------------------- 
1   93   Tapah   TAP 
1   3   Melaka   MLK 
1   6   Kota Bharu  KB 
1   7   Dungun   DG 
2   77   Grik   GRIK 
2   6   Kota Bharu  KB 
2   7   Dungun   DG 
2   98   Bangan Serai BS 
6   3   Melaka   MLK 
6   82   Teluk Intan TI 
6   7   Dungun   DG    

ответ

1

Причиной проблемы является неправильное использование JsonConvert.DeserializeObject следующего должен работать в этом случае:

определить тип/схемы с деталями колонн (как показано выше ответ)

public class City 
{ 
    public int cityId; 
    public string cityName; 
    public string cityCode; 
} 

Теперь то, что вы получаете в теле ответа является типом, Json является парой ключа значения по умолчанию

Dictionary<object, List<City>> 

Теперь ваш код десериализации должен быть:

var obj = JsonConvert.DeserializeObject<Dictionary<object, List<City>>>(responseBody); 

OBJ будет иметь тип Dictionary<object, List<City>>

Теперь создать схему объекта пользовательского набора данных следующим образом:

public class CustomDataset 
    { 
     public object from; 
     public int cityId; 
     public string cityName; 
     public string cityCode; 
    } 

Использовать простой Еогеасп для создать пользовательский набор данных из объекта obj следующим образом:

List<CustomDataset> cdList = new List<CustomDataset>(); 

foreach(object key in obj.Keys) 
{ 
foreach(City c in obj[key]) 
{ 
    cdList.Add(key, c.cityId, c.cityName, cityCode); 
} 
} 

cdList типа List<CustomDataset> wil будет вашим возвратом, содержащим решение, в котором вы нуждаетесь. Заключительная часть с использованием Foreach может быть пропущен, если вы используете Linq, который был бы просто следующим образом:

List<CustomDataset> cdList = 
           obj.SelectMany(x => x.Value.Select(y => 
               new CustomDataset 
               { 
               from = x.Key, 
               cityId = y.cityId, 
               cityName = y.cityName, 
               cityCode = y.cityCode 
               } 
               )).ToList(); 
+0

Зачем использовать тип '' object' для TKey'? JSON.NET достаточно умен, чтобы вызвать 'Convert.ToInt32()', если вместо этого вы используете тип 'int'. –

+0

@Steven Liekens Вы правы, я просто сделал реализацию generic –

+0

Спасибо Mrinal Kamboj – CnuVas

0

Я предлагаю десериализацией JSON объектов для каркасных типов, которые семантически эквивалентны. В вашем случае, JSON семантически эквивалентно IDictionary<TKey, ICollection<TValue>>>

IDictionary<int, ICollection<City>> cities; 
cities = JsonConvert.DeserializeObject<IDictionary<int, ICollection<City>>>(responseBody); 

Затем сделайте DataSet преобразование самостоятельно, вместо того, чтобы полагаться на отражение.

var dataSet = new DataSet(); 
var dataTable = dataSet.Tables.Add(); 
dataTable.Columns.Add("from"); 
dataTable.Columns.Add("cityId"); 
dataTable.Columns.Add("cityName"); 
dataTable.Columns.Add("cityCode"); 

// foreach KeyValuePair in IDictionary<TKey, ICollection<TValue>> 
foreach (var cityGroup in cities) 
{ 
    // foreach TValue in ICollection<TValue> 
    foreach (var city in cityGroup.Value) 
    { 
     dataTable.LoadDataRow(
      new object[] 
      { 
       cityGroup.Key, 
       city.cityId, 
       city.cityName, 
       city.cityCode 
      }, 
      LoadOption.PreserveChanges); 
    } 
} 

Для TValue я использовал простой класс данных для данных.

public class City 
{ 
    public int cityId; 
    public string cityName; 
    public string cityCode; 
} 
+0

Большое вам спасибо Steven Liekens – CnuVas