0

I'm trying to retrieve values that are stored in a JSON string that I obtain from a website using Newtonsoft.Json.

I have the code below, but I cant work out how to loop through the data to retrieve the Name tag within the Palette->Threads->Name section. The number of thread names may vary from 1 to 15.

The desired outcome of the code below would be to output something like Colours Used: Black, Light Blue, White etc

Any help would be much appreciated, I've racked my brains looking at other peoples examples, but I've had no luck in applying Dictionary or Lists (I'm still learning .net)

protected void Page_Load(object sender, EventArgs e)
        {
            string jsondata = "{\"Width\":295,\"Height\":329,\"NumStitches\":1596,\"NumTrims\":1,\"Left\":479,\"Top\":-868,\"Right\":775,\"Bottom\":-539,\"Recipe\":\"Normal\",\"MachineFormat\":\"Tajima\",\"MasterDensity\":40,\"Palette\":{\"Threads\":[{\"Name\":\"Black\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1000\",\"Red\":0,\"Green\":0,\"Blue\":0,\"Type\":\"ttRayon\",\"Thickness\":3},{\"Name\":\"Light Blue\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1029\",\"Red\":0,\"Green\":114,\"Blue\":207,\"Type\":\"ttRayon\",\"Thickness\":3},{\"Name\":\"White\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1001\",\"Red\":255,\"Green\":255,\"Blue\":255,\"Type\":\"ttRayon\",\"Thickness\":3},{\"Name\":\"Mustard Brown\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1165\",\"Red\":255,\"Green\":153,\"Blue\":51,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Midnight Blue\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1242\",\"Red\":0,\"Green\":40,\"Blue\":120,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Jungle Green\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1249\",\"Red\":0,\"Green\":204,\"Blue\":0,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Robin Egg Blue\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1093\",\"Red\":0,\"Green\":255,\"Blue\":255,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Hyacinth\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1112\",\"Red\":125,\"Green\":0,\"Blue\":153,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Aztec Gold\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1125\",\"Red\":255,\"Green\":240,\"Blue\":51,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Evergreen\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1303\",\"Red\":0,\"Green\":73,\"Blue\":51,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Lilac\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1033\",\"Red\":153,\"Green\":0,\"Blue\":153,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Jet Black\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1000\",\"Red\":0,\"Green\":0,\"Blue\":0,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Sapphire\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1076\",\"Red\":0,\"Green\":87,\"Blue\":150,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Bordeaux\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1035\",\"Red\":99,\"Green\":47,\"Blue\":61,\"Type\":\"ttCotton\",\"Thickness\":3},{\"Name\":\"Flesh\",\"Manufacturer\":\"Madeira 40\",\"Code\":\"1017\",\"Red\":244,\"Green\":188,\"Blue\":172,\"Type\":\"ttCotton\",\"Thickness\":3}]},\"Needles\":[1,2,3]}";
            var output = JsonConvert.DeserializeObject<jsonclass>(jsondata);
            int StitchCount = output.NumStitches;
            int StitchHeight = output.Height;
            int StitchWidth = output.Width;
            var pal = output.Palette;


    // The following code is wrong, but illustrates what I'm trying to do

            Response.Write("Colours used: ");

            foreach (thread in pal["Threads"])
            {
               Response.Write(thread["Name"] & ",");
            }

        }

        public class jsonclass
        {
            public int Width { get; set; }
            public int Height { get; set; }
            public int NumStitches { get; set; }
            public Object Palette { get; set; }
        }

I've stripped it down a bit, but this is a visual representation of the JSON data to help understand it

    {
    "Width":295,
    "Height":329,
    "NumStitches":1596,
    "Palette":
    {

        "Threads":
        [
            {

            "Name":"Black",
            "Manufacturer":"Madeira 40",
            "Code":"1000",
            "Red":0,
            "Green":0,
            "Blue":0,
            "Type":"ttRayon",
            "Thickness":3
            },

            {

            "Name":"Light Blue",
            "Manufacturer":"Madeira 40",
            "Code":"1029",
            "Red":0,
            "Green":114,
            "Blue":207,
            "Type":"ttRayon",
            "Thickness":3
            },

            {

            "Name":"White",
            "Manufacturer":"Madeira 40",
            "Code":"1001",
            "Red":255,
            "Green":255,
            "Blue":255,
            "Type":"ttRayon",
            "Thickness":3
            }
        ]},
    "Needles":[1,2,3]
}
3
  • A handy hint when mapping Json to a Class, is to install Web Essentials as it has something called "Paste Json as Classes". You can simply copy the json string, and paste into Visual Studio, which then creates the matching Class(s) for you. Commented Sep 9, 2014 at 13:56
  • what version of net framework do you use? try to use the "dynamic" instead of object public dynamic Palette { get; set; } You will be able to access any property in runtime. Commented Sep 9, 2014 at 14:02
  • @ViktorArsanov I found that example too, but I'm using v2 and it doesnt work :( Commented Sep 9, 2014 at 14:26

3 Answers 3

1

You should model your JsonClass as follow and add threads etc. as well:

public class JsonClass
{
  public int Width { get; set; }
  public int Height { get; set; }
  public int NumStitches { get; set; }
  public Palette Palette { get; set; }
}

public class Palette
{
  public IEnumerable<Thread> Threads { get; set; }
}

public class Thread
{
  public string Name { get; set;}
  ...
}

Then you can iterate over the threads with the following code:

foreach (var thread in pal.Threads)
{
  Response.Write(thread.Name + ", ");
}
Sign up to request clarification or add additional context in comments.

4 Comments

This is what I tried attempting, but couldn't figure out! I am having one more trouble with this though, when I add the foreach loop, the word 'thread' is squiggly underlined with the caution "The type or namespace name 'thread' could not be found(are you missing a using directive or an assembly reference?)"
@Chris sorry I can't imagine what your problem is. I've tried exactly my code and it worked. Do you have the foreach-loop exactly like in my example? Do you maybe have some other references to something similar? What happens if you rename thread to e.g. myTempVariable?
Thanks Kevin, your answer works now! Funnily enough, the other reply with similar answer to yours from BruceWayne had the same issue, the word "var" was missed in the foreach loop, which stopped it from running. I tried using "string" but it said computer says no, I didnt think to use var.
@Chris, Kevin made the same small tech typo which I fixed (missing var), but you should slowly learn to fix such typos or small irregularities in the code rather than asking why it doesn't work. Obviously thread cannot be a string, because you are iterating over a collection of objects of type Thread. So it's simply, in plain English, for each object of type thread in the Threads collection -> do this. Var is a keyword that lets the compiler decide what to replace it with, in this case it knows those are Thread objects but you could simply write "Thread thread in pal.Threads" there as well.
1

use the following model to Deserialise your json.

     public class Palette
     {
       public List<Thread> Threads { get; set; }
     }
      public class Thread
   {
public string Name { get; set; }
public string Manufacturer { get; set; }
public string Code { get; set; }
public int Red { get; set; }
public int Green { get; set; }
public int Blue { get; set; }
public string Type { get; set; }
public int Thickness { get; set; }
}

   public class Colors
{
public int Width { get; set; }
public int Height { get; set; }
public int NumStitches { get; set; }
public Palette Palette { get; set; }
public List<int> Needles { get; set; }
}

On page load

 var output = JsonConvert.DeserializeObject<Colors>(jsondata);

then iterate the thread

  foreach(var thread in output.Palette.Threads){
 //something like you wanted
   Response.Write(thread.Name + ",");
 }

2 Comments

This looks really easy to follow, but I get the same error as another example above. The word 'thread' is squiggly underlined with the caution "The type or namespace name 'thread' could not be found(are you missing a using directive or an assembly reference?)"
BEAUTIFUL! Thank you so much. It says I cant up vote though as only just joined!
0

Solution using JSON.NET built-in LINQ to JSON provider:

JObject jObject = JObject.Parse(jsondata);

JArray threads = (JArray)jObject["Palette"]["Threads"];

var colorsUsed = new StringBuilder();
colorsUsed.Append("Colours used: ");

foreach (var thread in threads)
{
    colorsUsed.AppendFormat("{0}, ", thread["Name"]);
}

Response.Write(colorsUsed);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.