将JsonObjects反序列化为.NET对象

时间:2012-02-11 05:41:06

标签: c# json.net

尝试使用Json.Net将以下JSON反序列化为.NET对象并不是按预期进行的。反序列化通常不是一个主要的复杂因素,但以下JSON的结构并不是直接的。

JSON:

{
    "33": {
        "0": {
            "StopName": "JFK Blvd & 15th St",
            "Route": "33",
            "date": "11:24p",
            "day": "Fri",
            "Direction": "1",
            "DateCalender": "02/10/12 11:24 pm"
        },
        "3": {
            "StopName": "JFK Blvd & 15th St",
            "Route": "33",
            "date": "11:52p",
            "day": "Fri",
            "Direction": "1",
            "DateCalender": "02/10/12 11:52 pm"
        }
    },
    "32": {
        "1": {
            "StopName": "JFK Blvd & 15th St",
            "Route": "32",
            "date": "11:30p",
            "day": "Fri",
            "Direction": "1",
            "DateCalender": "02/10/12 11:30 pm"
        }
    },
    "17": {
        "2": {
            "StopName": "JFK Blvd & 15th St",
            "Route": "17",
            "date": "11:38p",
            "day": "Fri",
            "Direction": "1",
            "DateCalender": "02/10/12 11:38 pm"
        }
    }
}

复杂性来自" 33"," 32"," 17"代表路线编号。这些数字可能会随着结果集中的路径发生变化而改变。

我确定我需要为此编写自定义JSON转换器,但我无法找到有关完成此任务的任何明确信息(因为似乎没有人遇到问题属性名称是动态的。

我还尝试将JSON.NET Linq用于JSON,但这不可行,因为您需要使用类似于以下代码来访问JSON:

JObject o = JObject.Parse(e.Result);
o["33"];

由于我没有现实的想法,事先知道属性名称是什么,我似乎很容易遍历这个对象。

2 个答案:

答案 0 :(得分:3)

你的json格式:

{
    "33": { <-- This is MainRoute number
        "0": { <-- This is SubRoute number and below are SubRoute properties
            "StopName": "JFK Blvd & 15th St",
            "Route": "33",                        
            "date": "11:24p",                   
            "day": "Fri",
            "Direction": "1",
            "DateCalender": "02/10/12 11:24 pm"
        },
     ....
}

您可以使用JObject来解析您的json数据:

public class MainRoute {
        public int RouteNumber { get; set; }
        public IList<SubRoute> SubRoutes { get; set; }

        public MainRoute()
        {
                SubRoutes = new List<SubRoute>();
        }
}

public class SubRoute {
        public int RouteNumber { get; set; }
        public string StopName { get; set; }
        public int Route { get; set; }

        [JsonProperty("date")]
        public string Date { get; set; }

        [JsonProperty("day")]
        public string Day { get; set; }
        public int Direction { get; set; }

        [JsonProperty("DateCalender")]
        public string DateCalendar { get; set; }
}

class Program {
        static void Main(string[] args)
        {
                string jsonString = FetchJsonData();
                var routes = ParseRouteJsonString(jsonString);
        }

        static IEnumerable<MainRoute> ParseRouteJsonString(string jsonString)
        {
                JObject jsonObject = JObject.Parse(jsonString);
                foreach (KeyValuePair<string, JToken> pair in jsonObject) {
                        var mainRoute = new MainRoute() {
                                RouteNumber = Int32.Parse(pair.Key) // Get main route number.
                        };

                        foreach (JProperty property in pair.Value) {
                                var subRoute = property.Value.ToObject<SubRoute>();
                                subRoute.RouteNumber = Int32.Parse(property.Name); // Get sub route number.
                                mainRoute.SubRoutes.Add(subRoute);
                        }

                        yield return mainRoute;
                }
        }
}

答案 1 :(得分:3)

以下是使用linq到json迭代路径的一小部分示例:

var main = JObject.Parse(json);
foreach (var mainRoute in main.Properties())
{
    Console.WriteLine(mainRoute.Name); //33, 32, ... 
    foreach (var subRoute in mainRoute.Values<JObject>().SelectMany(x => x.Properties()))
    {
        Console.WriteLine(" " + subRoute.Name); //0, 3, ... 
        var routeData = subRoute.Value as JObject;
        foreach (var dataItem in routeData.Properties())
        {
            Console.WriteLine(string.Format("  {0} = {1}", dataItem.Name, dataItem.Value.Value<string>()));
        }
    }
}