1

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.

2
  • 1
    when calling, what object are you passing into your extension method? Commented Jun 21, 2012 at 5:14
  • @prashantht, I just call my extension method like that var _CountryNState = objRepository.CountryNState_Select_Lookup().CountryNState; /// which is generic List object _CountryNState.ToJSON(); Commented Jun 21, 2012 at 5:20

3 Answers 3

3

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...

Sign up to request clarification or add additional context in comments.

1 Comment

you answer help me a lot, thank you very much @Leland Richardson
3

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

Comments

1

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.