parse JSON array with json.NET and C#

19,497

Solution 1

@competent_tech is correct in is analysis. If I can propose, I think it'll feel more natural if you work with actual objects. For example:

public class RouteInfo
{
    public List<string> Directions { get; set; }
    public string RouteID { get; set; }
}

public class RouteData
{
    public int Status { get; set; }
    public string Timestamp { get; set; }
    public List<RouteInfo> Routes { get; set; }
}

And in your method:

var routeData = JsonConvert.DeserializeObject<RouteData>(e.Result);
return routeData.Routes
                .Select(r => new Route
                    {
                        routeId = r.RouteID,
                        directions = String.Join(" - ", r.Directions)
                    })
                .OrderBy(r =­> r.routeId)
                .ToList();

Or manipulate your type object in other ways, more naturally.

Edit: For an easy way to generate classes based on a JSON string, go to json2csharp.

Solution 2

This is because your routeDirections is specifically asking for the first element in the array:

JArray routeDirections = (JArray)routeData["routes"][0]["directions"];

You need to move this logic inside the loop and use the current loop indexer:

for (int i = 0; i < routeIdArray.Count; i++)
{
    Route BusRoutes = new Route();

    JObject routeIDarrayObject = (JObject)routeIdArray[i];
    BusRoutes.routeID = (string)routeIDarrayObject["routeID"];

    JArray routeDirections = routeIDarrayObject["directions"];
Share:
19,497

Related videos on Youtube

IanMitz
Author by

IanMitz

Updated on June 07, 2022

Comments

  • IanMitz
    IanMitz almost 2 years

    I have some data in the following JSON format that I need to parse:

    {
    "status":0,
    "timestamp":"8:20pm",
    "routes":[
        {
            "directions":[
                "E Towne",
                "ETP"
            ],
            "routeID":"30"
        },
        {
            "directions":[
                "Johnson",
                "Observatory"
            ],
            "routeID":"81"
        }
    ]
    }
    

    Using json.net, I have got want to get the following output:

    30 E Towne – ETP

    81 Johnson – Observatory

    Using the code below, I get the following incorrect output:

    30 E Towne – ETP

    81 E Towne – ETP

    How do I write out the directions array items to the corresponding routeID item? My code:

    public class Route
            {
                public string routeID { get; set; }
                public string directions { get; set; }  
            }
    
    private void routeClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e) 
            {
                string jsonResults_routes = e.Result;
                JObject routeData = JObject.Parse(jsonResults_routes);
    
                JArray routeIdArray = (JArray)routeData["routes"];
                JArray routeDirections = (JArray)routeData["routes"][0]["directions"];
    
                List<Route> l = new List<Route>();
    
                for (int i = 0; i < routeIdArray.Count; i++)
                {
                    Route BusRoutes = new Route();
    
                    JObject routeIDarrayObject = (JObject)routeIdArray[i];
                    BusRoutes.routeID = (string)routeIDarrayObject["routeID"];
    
                    string sep = " - ";
                    string bothDirections = String.Join(sep, routeDirections);
    
                    List<string> sc = new List<string>();
                    string[] direction = new string[]{bothDirections};
                    sc.AddRange(direction);
    
                    foreach (string direx in sc)
                    {
                        BusRoutes.directions = direx; 
                    }
    
                    l.Add(BusRoutes);
    
                }
                var newList = l.OrderBy(x => x.routeID).ToList();
                lbRoutesData.ItemsSource = newList;
            }
    
  • IanMitz
    IanMitz almost 11 years
    in your method example, in line 3, should "new Route" be "new RouteInfo"? Also, where is "routeId" and "directions" defined
  • Simon Belanger
    Simon Belanger almost 11 years
    No, because RouteInfo refers to the class representation of the Json object whereas Route represents the expected return type (see the original question, it's in the last code block). It is also where routeId and directions is defined. I just reused your class.
  • IanMitz
    IanMitz almost 11 years
    OK. So, I have 3 public classes in my final code ('Route', 'RouteInfo', 'RouteData')? And how do I tie your example method into my code i.e. passing the data to my 'var newlist' ?
  • IanMitz
    IanMitz almost 11 years
    thanks for the help and sorry for the delay in confirming the answer. I only just got back to working on this project