0

I am working on a C# project where I need to call an API and parse through the JSON response.

The JSON response:

{
    "version": "3.9.1",
     "data": {
        "obj1": {
            "version": "1.0.0",
            "id": "obj1",
            "name": "Object 1",
            "title": "Object 1",
            "info": {
                "info1": 8,
                "info2": 4,
                "info3": 3
            },
            "image": {
                "full": "Object1.png",
                "w": 64,
                "h": 64
            },
            "tags": [
                "Tag1",
                "Tag2"
            ]
        },
        "obj2": {
            "version": "1.0.0",
            "id": "obj2",
            "name": "Object 2",
            "title": "Object 2",
            "info": {
                "info1": 1,
                "info2": 6,
                "info3": 7
            },
            "image": {
                "full": "Object2.png",
                "w": 64,
                "h": 64
            },
            "tags": [
                "Tag1",
                "Tag6"
            ]
        },
        "obj3": {
            "version": "1.0.0",
            "id": "obj3",
            "name": "Object 3",
            "title": "Object 3",
            "info": {
                "info1": 0,
                "info2": 1,
                "info3": 2
            },
            "image": {
                "full": "Object3.png",
                "w": 64,
                "h": 64
            },
            "tags": [
                "Tag7",
                "Tag8"
            ]
        }
    }
}

With this response, I want to loop through all the objects located inside data. The number of objects inside data isn't always the same; it is possible that there will only be one object or ten objects.

The problem I ran into is that I can't loop through the data property because of the following error:

foreach statement cannot operate on variables of type 'Objects' because 'Objects' does not contain a public instance or extension definition for 'GetEnumerator'

I know why I am getting the error, but I can't find a way of fixing my problem.

My code:

MainWindow.xaml.cs

WebRequest request = WebRequest.Create(path);
WebResponse response = request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream());

string ReaderJson = reader.ReadToEnd();

var JsonResponse = JsonConvert.DeserializeObject<Response>(ReaderJson);

foreach (var obj in JsonResponse.data)
{
    Console.WriteLine(obj.ToString());
}

JsonParser.cs

    public class Response
    {
        public string version { get; set; }
        public Objects data { get; set; }
    }

    public class Objects
    {
        public string id { get; set; }
        public string name { get; set; }
        public string title { get; set; }
        public Info info { get; set; }
        public Images images { get; set; }
    }

    public class Info
    {
        public int info1 { get; set; }
        public int info2 { get; set; }
        public int info3 { get; set; }
    }

    public class Images
    {
        public string full { get; set; }
        public int w { get; set; }
        public int h { get; set; }
    }

How can I loop through all the objects inside data without calling them using obj1, obj2, etc.?

4
  • I'm guessing that data is not what you're thinking it is. It looks like data is an object, not a collection. Commented May 3, 2021 at 20:30
  • 2
    Your data model doesn't map to your JSON data. Your data property should be a Dictionary<string, Objects>. (As an aside, the class name Objects is a bit peculiar here; only collections should be named as plurals.) Commented May 3, 2021 at 20:40
  • ahh alright thanks! and yes I wanted to rename the Objects class afterwards but I first wanted to fix this problem. Just a bad practice that I sadly enough do quite often. Commented May 3, 2021 at 21:01
  • 1
    FYI: I formalized that comment as an answer with a bit more detail—though it sounds like you already got the main points from my comment. Let me know if that works for you! Commented May 3, 2021 at 21:03

1 Answer 1

1

The problem here is that your JSON schema defines a dictionary for data, but your data property returns a single instance of your Objects class.

Data Model

What you want is for your Response class to look something like this:

public class Response
{
    public string version { get; set; }
    public Dictionary<string, Objects> data { get; set; }
}

Everything else should be fine.

Looping Through Data

Given the above, you can now loop through the data dictionary using something like:

foreach (var obj in JsonResponse.data)
{
    Console.WriteLine(obj.Key);
}

Note: When looping through a Dictionary<TKey, TValue>, an enumeration of KeyValuePair<TKey, TValue>s will be returned, with your key (i.e., obj1) in the Key property, and your object in the Value property.

Naming Conventions

Obviously, the name Objects doesn't makes sense here, since it represents a single object, not a collection of objects. I'm keeping it Objects for consistency with your code, but you'll want to give it a singular name. I assume that was just left over from you wanting it to represent a collection.

Sign up to request clarification or add additional context in comments.

2 Comments

@MrMilkshake: Glad to hear! As an aside, if you control the data, an alternative approach would be to treat data as an array in your JSON, and then map it to a Collection<>—or, if you still want it to be keyed, then a KeyedCollection<> based on your id property.
Yeah it would be alot easier if data was indeed a array but sadly enough the JSON comes as a response from an API and I am not able to change it :( but the KeyedCollection<> is a great alternative i'll give it a try :D

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.