0

I have the following JSON stored in a cookie that I wish to parse:

{"package":[{"id":"5054","nodeId":"3286"},{"id":"8888","nodeId":"7777"}], "hotel":[{"id":"3421","nodeId":"1234"},{"id":"8748","nodeId":"2435"}], "activity":[{"id":"5054","nodeId":"3286"},{"id":"8888","nodeId":"7777"},{"id":"2131","nodeId":"2342"}]}

I understand from the accepted answer on this question Deserializing JSON to .NET object using Newtonsoft (or LINQ to JSON maybe?) that you can use the following code to access individual objects within JSON notation:

JToken token = JObject.Parse(stringFullOfJson);

int page = (int)token.SelectToken("page");
int totalPages = (int)token.SelectToken("total_pages");

I've therefore adapted this into my code as follows:

HttpCookie cookie = Request.Cookies.Get("wishlist");
string JSONstring = string.Empty;
string nodeId = string.Empty;

if (cookie != null)
{
    JSONstring = cookie.Value;
    JToken token = JObject.Parse(JSONstring);
}

I now wish to only retreive the package array for example and loop through each of the items in this array and output the ids in the following format:

5054,8888

From the example code I sort of came up with the following approach but i'm not sure if i'm proceeding in the right direction.

JObject obj = JObject.Parse(JSONstring);
JArray packages = (JArray)obj["package"];

What is the best way of specifying one of the arrays eg. hotel, package , looping through their contents and outputting each of the id nodes that are found? The nodeId will always be numeric but the id could be a string or an int so this adds another layer of complication.

Any help would be greatly appreciated and I apologise if this is a sumwhat stupid or easy question however I have jsut started working with .Net and OO so some of the concepts are still a bit foggy.

Community
  • 1
  • 1
jezzipin
  • 4,110
  • 14
  • 50
  • 94

2 Answers2

1

Here's How I would Do This, I'd Create the classes required to Deserialize the JSON :-

    public class JSONCookie
    {
        public Package[] package { get; set; }
        public Hotel[] hotel { get; set; }
        public Activity[] activity { get; set; }
    }

    public class Package
    {
        public string id { get; set; }
        public string nodeId { get; set; }
    }

    public class Hotel
    {
        public string id { get; set; }
        public string nodeId { get; set; }
    }

    public class Activity
    {
        public string id { get; set; }
        public string nodeId { get; set; }
    }

Now, I would Create a method that actually does the deserialising :-

public JSONCookie GetJSONCookieResponse()
        {
            try
            {
                // Add your own code that gets the Response Here.

                // string response = "{"package":[{"id":"5054","nodeId":"3286"},{"id":"8888","nodeId":"7777"}], "hotel":[{"id":"3421","nodeId":"1234"},{"id":"8748","nodeId":"2435"}], "activity":[{"id":"5054","nodeId":"3286"},{"id":"8888","nodeId":"7777"},{"id":"2131","nodeId":"2342"}]}";

                //return new JsonSerializer().Deserialize<JSONCookie>(new JsonTextReader(new StringReader(response)));
            }
            catch
            {
                return null;
            }
        }

From the JSONCookie Object that is returned, you can then use LINQ to pick out what you need like follows :-

x.package.Select(p=>p.id);
Derek
  • 8,300
  • 12
  • 56
  • 88
  • Thanks for this Derek. I neglected to mention that this will all be run in a razor view so as far as I know, classes aren't really an option and are probably a little heavyweight for this solution. – jezzipin Jun 27 '14 at 11:12
  • @Derek You don't need 3 diffeent classes *Package* *Hotel* and *Activity*. A single class *Node* is enough – L.B Jun 27 '14 at 11:40
0

After a lot of trawling Google, this is the easiest solution I have come up with:

HttpCookie cookie = Request.Cookies.Get("wishlist");
string JSONstring = string.Empty;
string nodeId = string.Empty;
string test = string.Empty;

if (cookie != null)
{
    JSONstring = cookie.Value;
    JObject obj = JObject.Parse(JSONstring);
    JArray packages = (JArray)obj["package"];

    foreach (var item in packages.Children()){
        var properties = item.Children<JProperty>();
        var idElement = properties.FirstOrDefault(x => x.Name == "id");
        var myElementValue = idElement.Value;

        test = test + myElementValue + ",";
    }
}

This will output all ids in the packages array in a CSV format (with a trailing ,)

jezzipin
  • 4,110
  • 14
  • 50
  • 94
  • 1
    Wouldn't this be shorter: `var jObj = JsonConvert.DeserializeObject>>(JSON); var csv = String.Join(",", jObj.SelectMany(x => x.Value).Select(x => x.id));` – L.B Jun 27 '14 at 12:18
  • Well this seems to work but could you explain it in a little more detail for myself and others to understand then maybe I will be able to mark it as the correct answer – jezzipin Jun 27 '14 at 12:26