Reputation: 4474
I have a Generic List
object which hold below table as its own value.
CountryID | StateID | StateName
--------------------------------
1 | 1 | Alabama
1 | 2 | California
1 | 3 | Florida
1 | 4 | Hawaii
2 | 5 | London
2 | 6 | Oxford
I would like to create JSON string according to that List object. The JSON format which i would like to get is like below.
{
1: { '1': 'Alabama', '2': 'California', '3': 'Florida', '4': 'Hawaii' },
2: { '5': 'London', '6': 'Oxford' }
};
I used below class to generate JSON object.
public static class JSONHelper
{
public static string ToJSON(this object obj)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
return serializer.Serialize(obj);
}
public static string ToJSON(this object obj, int recursionDepth)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RecursionLimit = recursionDepth;
return serializer.Serialize(obj);
}
}
But , the actual output that I got when I finished calling ToJSON
method is like below.
{
[
{"CountryID":1,"StateID":1,"StateName":"Alabama"},
{"CountryID":1,"StateID":2,"StateName":"California"},
{"CountryID":1,"StateID":3,"StateName":"Florida"},
{"CountryID":1,"StateID":4,"StateName":"Hawaii"},
{"CountryID":2,"StateID":5,"StateName":"London"},
{"CountryID":2,"StateID":6,"StateName":"Oxford"}
]
}
So , Could anyone please give me suggestion how could I make JSON string format as I want ?
Every suggestion will be appreciated.
Upvotes: 1
Views: 840
Reputation: 192417
You need to serialize a dictionary, not a list, to get that JSON. Given these type definitions:
public class Country
{
public Country()
{
States = new List<State>();
}
public int CountryID { get; set; }
public List<State> States { get; set; }
}
public class State
{
public int StateID { get; set; }
public string StateName { get; set; }
}
And this variable:
var clist = new List<Country>();
I can serialize to the format you desire with this code:
var d = clist.ToDictionary
(k => k.CountryID.ToString(),
e => e.States.ToDictionary(k2 => k2.StateID.ToString(),
e2 => e2.StateName));
Console.WriteLine("{0}",JSONHelper.ToJSON(d));
This uses the ToDictionary()
extension method that is part of LINQ.
output:
{"1":{"1":"Lzwuoge","2":"0lzpas"},"2":{"1":"Mqn3ul5k","2":"Kefzu"}}
Upvotes: 3
Reputation: 2695
It seems like a simple way to do this would be to use LINQ to select into a dictionary, and then send the dictionary object to the JavascriptSerializer...
priveded we have:
var list = new[]
{
new {CountryID = 1, StateID = 1, StateName = "Alabama"},
new {CountryID = 1, StateID = 2, StateName = "California"},
new {CountryID = 1, StateID = 3, StateName = "Florida"},
new {CountryID = 1, StateID = 4, StateName = "Hawaii"},
new {CountryID = 2, StateID = 5, StateName = "London"},
new {CountryID = 2, StateID = 6, StateName = "Oxford"}
};
then we can call .ToDictionary recursively on it to get the following:
var d = list
.GroupBy(x=>x.CountryID)
.ToDictionary(g=> g.Key.ToString(),
g => g.ToDictionary(x => x.StateID.ToString(),x => x.StateName));
var serializer = new JavaScriptSerializer();
return serializer.Serialize(d);
which returns the JSON you requested
NOTE: you have to call the .ToString() on the dictionary Keys as the JavaScriptSerializer seems to fail on Dictionarys with keys that arent strings...
Upvotes: 3
Reputation: 5893
The simplest way to convert it to the format you specify is to convert your custom class to a nested dictionary:
Dictionary<Int32,Dictionary<String, String>>
and then serialize that output.
Dictionary<Int32,Dictionary<String, String>> countryDict= new Dictionary<Int32,Dictionary<String, String>>()
foreach(var item in myGenericList){
Dictionary<Int32,Dictionary<String, String> stateDict =
countryDict[item.CountryID] ?? new Dictionary<Int32,Dictionary<String, String>>();
stateDict.Add(item.StateID.ToString(),item.StateName)
}
Upvotes: 1