c#转换字典<object,list <object =“”>&gt;到JSON

时间:2016-05-24 20:16:15

标签: c# angularjs json dictionary

我在database中有两个表,有一对多关系.State有很多Cities.I从数据库中获取这些数据并将relationship转换为c#中对象的逻辑。

Dictionary<State, List<City>>转换为JSON,然后使用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;
}

它给我 500内部服务器错误

  

{ “消息”:“类型   \ u0027System.Collections.Generic.Dictionary2 [[AngularWeb.State,   AngularWeb,版本= 1.0.0.0,文化=中立,   公钥=空],[System.Collections.Generic.List1 [[AngularWeb.City,   AngularWeb,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]],   mscorlib,版本= 4.0.0.0,文化=中性,   不支持PublicKeyToken = b77a5c561934e089] \ u0027   字典的序列化/反序列化,键必须是字符串或   对象。“,”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(对象   o,StringBuilder sb,Int32 depth,Hashtable objectsInUse,   SerializationFormat serializationFormat,MemberInfo currentMember)\ r \ n   在   System.Web.Script.Serialization.JavaScriptSerializer.SerializeValue(对象   o,StringBuilder sb,Int32 depth,Hashtable objectsInUse,   SerializationFormat serializationFormat,MemberInfo currentMember)\ r \ n   在   System.Web.Script.Serialization.JavaScriptSerializer.Serialize(对象   obj,StringBuilder输出,SerializationFormat   serializationFormat)\ r \ n at   System.Web.Script.Serialization.JavaScriptSerializer.Serialize(对象   obj,SerializationFormat serializationFormat)\ r \ n at   System.Web.Script.Services.RestHandler.InvokeMethod(HttpContext的   context,WebServiceMethodData methodData,IDictionary`2 rawParams)\ r \ n   在   System.Web.Script.Services.RestHandler.ExecuteWebServiceCall(HttpContext的   context,WebServiceMethodData   methodData)”, “ExceptionType”: “System.ArgumentException”}

我不确定json的正确语法,但我想要显示这样的东西:

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

谢谢!

1 个答案:

答案 0 :(得分:1)

虽然C#可以Dictionary<object, object>,但Serialization Guide表示:

  

序列化字典时,字典的键将转换为字符串并用作JSON对象属性名称。为密钥编写的字符串可以通过覆盖密钥类型的ToString()或通过实现TypeConverter来自定义。在反序列化字典时,TypeConverter还将支持再次转换自定义字符串。

基本上,它说你不能使用State作为关键。你有几个选择。

  1. 将州和城市作为Dictionary<string, object>发送,并让前端为您处理关系。
  2. 创建一个负责后端关系的匿名类。
  3. 这两种方法都记录在这里。

    方法1:以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);
    }
    

    方法2:以List<Anonymous Class>

    发送

    基本思想是创建一个匿名类型对象列表(或者您可以创建自己的类)。您可以拨打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);
    }