2

I have two tables in database with one to many relationship.State have many Cities.I get those data from database and convert their relationship to the logic of object in c#.

Convert Dictionary<State, List<City>>to JSON and display then using AngularJs.

[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]
public static Dictionary<State, List<City>> GetCitiesState()
{
    List<State> stateList = new List<State>();
    stateList = StateList();
    List<City> cityList = new List<City>();
    cityList = CityList();
    List<City> currentList = new List<City>();

    Dictionary<State, List<City>> dictionary = new Dictionary<State, List<City>>();
    bool found = false;
    foreach (State state in stateList)
    {
        foreach (City city in cityList)
        {
            if (state.Id == city.StateId)
            {
                found = true;
                currentList.Add(city);
            }
        }
        if (found)
        {
            dictionary.Add(state, currentList);
        }
    }
    return dictionary;
}

It give me 500 Internal Server Error

{"Message":"Type \u0027System.Collections.Generic.Dictionary2[[AngularWeb.State, AngularWeb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null],[System.Collections.Generic.List1[[AngularWeb.City, AngularWeb, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]\u0027 is not supported for serialization/deserialization of a dictionary, keys must be strings or objects.","StackTrace":" at System.Web.Script.Serialization.JavaScriptSerializer.SerializeDictionary(IDictionary o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat)\r\n at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValueInternal(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat, MemberInfo currentMember)\r\n at System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(Object o, StringBuilder sb, Int32 depth, Hashtable objectsInUse, SerializationFormat serializationFormat, MemberInfo currentMember)\r\n at System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, StringBuilder output, SerializationFormat serializationFormat)\r\n at System.Web.Script.Serialization.JavaScriptSerializer.Serialize(Object obj, SerializationFormat serializationFormat)\r\n at System.Web.Script.Services.RestHandler.InvokeMethod(HttpContext context, WebServiceMethodData methodData, IDictionary`2 rawParams)\r\n at System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext context, WebServiceMethodData methodData)","ExceptionType":"System.ArgumentException"}

I am not sure the correct syntax of json ,but I want to dispaly something like this:

STATE
 CITY
 CITY
 CITY
STATE
 CITY
 CITY
 CITY
......

Thank You!

Pawan Nogariya
  • 8,330
  • 12
  • 52
  • 105
Fation Hadri
  • 160
  • 2
  • 2
  • 20
  • 1
    There's no question mark in that text. Does the code compile? If not, what's the error message? Does it compile but fail? If so, what's the error message? Does it run and return JSON but not what you expect? Tell us what the output is and what you expect. – Thomas Weller May 24 '16 at 20:17
  • Possible duplicate of [How do I convert a dictionary to a JSON String in C#?](http://stackoverflow.com/questions/5597349/how-do-i-convert-a-dictionary-to-a-json-string-in-c) – layonez May 24 '16 at 20:19
  • 1
    @ThomasWeller, I edited the question.Thanks for alerting me for those extra information. – Fation Hadri May 24 '16 at 20:38

1 Answers1

1

While it's okay in C# to have Dictionary<object, object>, the Serialization Guide states that:

When serializing a dictionary, the keys of the dictionary are converted to strings and used as the JSON object property names. The string written for a key can be customized by either overriding ToString() for the key type or by implementing a TypeConverter. A TypeConverter will also support converting a custom string back again when deserializing a dictionary.

Essentially, it's saying that you can't use State as a key. You have several options.

  1. Send the states and cities as a Dictionary<string, object> and have the front end take care of the relationship for you.
  2. Create an anonymous class that takes care of the relationship in the backend.

Both methods are documented here.

Method 1: Send as a Dictionary<string, object>

[WebMethod]
public static string GetCitiesState()
{
    Dictionary<string, object> result = new Dictionary<string, object>();

    List<State> states = StateList();
    List<City> cities = CityList();

    result.Add("states", states);
    result.Add("cities", cities);

    return new JavaScriptSerializer().Serialize(result);
}

Method 2: Send as a List<Anonymous Class>

The basic idea is to create a list of anonymous typed objects (or you can make your own class). You can call new List<object>();.

[WebMethod]
public static string GetCitiesState()
{
    var result = new List<object>();

    //get stateList and cityList
    //etc... your code here etc...
    boolean found=false;
    foreach(State state in stateList)
    {
        var currentState = new {
            id = state.Id,
            state = state.State,
            stateName = state.Name,
            cities = new List<City>()
        };

        foreach(City city in cityList)
        {
            if(city.StateId == state.Id)
            {
                found=true;
                currentState.cities.Add(city);
            }
        }

        if(found )
        { 
        //add it to the running state list,only states that have cities.
        //on this situation it does not make sense because every states have  
        //cities but for extra info                                                                                              
        result.Add(currentState);
        }
    }

    return new JavaScriptSerializer().Serialize(result);
}
Fation Hadri
  • 160
  • 2
  • 2
  • 20
Kyle
  • 5,407
  • 6
  • 32
  • 47
  • Json format it is exactly what i am looking for.It will be more easy if i had model but i haven't and that it is the reason i have used Dictionary.Maybe it is an invalid dictionary as you say.I am trying to implement database relationship in object relationship using Dictionary. – Fation Hadri May 24 '16 at 21:24
  • @FationHadri See edit. – Kyle May 25 '16 at 13:00
  • Making a object as a key is a weired solution.Thanks a lot for you ideas! – Fation Hadri Jun 02 '16 at 17:35