Deserialize JSON String into DataTable / DataSet using c#

对着背影说爱祢 提交于 2019-12-14 02:42:49

问题


I have following JSON String

{
"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"}
    ]
}

When I using JSON.NET

DataSet obj = JsonConvert.DeserializeObject(responseBody);

I am getting following Table only

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

I need to like this

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:


The reason for the issue is the incorrect usage of the JsonConvert.DeserializeObject following should work in this case:

Define a type / schema with the columns details (as shown in above response)

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

Now what you are getting in response body is the type, Json is by default key value pair

Dictionary<object, List<City>>

Now your deserialization code should be:

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

obj will be of the type Dictionary<object, List<City>>

Now create the Schema of the Custom Dataset object as follows:

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

Use simple foreach to create the custom dataset from obj type as follows:

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 of type List<CustomDataset> wil be your return containing solution you need. Final part using Foreach can be skipped if you use Linq, which would be simple as follows:

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();



回答2:


I suggest de-serializing JSON objects to framework types that are semantically equivalent. In your case, the JSON is semantically equivalent to IDictionary<TKey, ICollection<TValue>>>

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

Then, do the DataSet conversion yourself instead of relying on reflection.

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

For TValue, I used a simple data contract class.

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


来源:https://stackoverflow.com/questions/26970797/deserialize-json-string-into-datatable-dataset-using-c-sharp

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!