-3

I know it sounds basic but all answers around this question have been stupidly large and bulky code that does not allow the functionality i need. i need to parse this json array.

[
   {
      "label":"Cow (1)",
      "value":3309
   },
   {
      "label":"Cow (1)",
      "value":14998
   },
   {
      "label":"Cow (4)",
      "value":20969
   },
   {
      "label":"Cow (4)",
      "value":20970
   },
   {
      "label":"Cow (4)",
      "value":20971
   },
   {
      "label":"Cowardly Bandit",
      "value":1886
   },
   {
      "label":"Cow calf (1)",
      "value":2310
   },
   {
      "label":"Coward in armour (82)",
      "value":5097
   },
   {
      "label":"Coward with bow (105)",
      "value":6049
   },
   {
      "label":"Cow calf (1)",
      "value":20979
   },
   {
      "label":"Undead cow (4)",
      "value":1691
   },
   {
      "label":"Plague cow",
      "value":1998
   },
   {
      "label":"Plague cow",
      "value":1999
   },
   {
      "label":"Unicow (57)",
      "value":5603
   },
   {
      "label":"Zombie cow (1)",
      "value":18597
   },
   {
      "label":"Zombie cow (1)",
      "value":20928
   },
   {
      "label":"Super Cow (5)",
      "value":21497
   },
   {
      "label":"Dairy cow",
      "value":22418
   },
   {
      "label":"Armoured cow thing (62)",
      "value":5986
   },
   {
      "label":"Armoured cow thing (62)",
      "value":6048
   }
]

And when i try to access the data point inside the array it returns null, code:

Stream stream = client.OpenRead("http://services.runescape.com/m=itemdb_rs/bestiary/beastSearch.json?term=" + Input);
StreamReader reader = new StreamReader(stream);
jObject = JObject.Parse(reader.ReadToEnd());
stream.Close();
//put items into list view
// i is the number where the json object is in the array 
var lvi = new ListViewItem(new string[] { (string)jObject[i]["label"], (string)jObject[i]["value"] }); 

I do not want to use classes

3
  • 5
    I do not want to use classes Then you've made a strange decision in choosing to use an object-oriented language. Commented Jan 12, 2017 at 11:40
  • 2
    convert it to a dynamic list and access the details you want Commented Jan 12, 2017 at 11:40
  • Are you sure you get the correct data from that webservice? Maybe read that reader.ReadToEnd() into a string variable that you can inspect, before trying to parse it. Commented Jan 12, 2017 at 11:41

3 Answers 3

2

Found error in your code. Instead:

JObject.Parse(reader.ReadToEnd());

Write (JObject -> JArray):

string text = reader.ReadToEnd();
var jObject = JArray.Parse(text);

Also when write operation in 2 lines, you will see where the error: in reading from the stream or in serialization.

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

Comments

1

Not wanting to use classes is weird but not impossible.

var json = reader.ReadToEnd();
var objects = JsonConvert.DeserializeObject<dynamic[]>(json);
var lvi = new ListViewItem(new string[] { (string)objects[i].label, (string)objects[i].value }); 

3 Comments

Thankyou.. the reason for avoiding classes is because that has a set amount of variables where the secondary json that needs to be recieved has over 100 variables inside said json.. making a class for that would be ridiculous at best
@Offnix The JSON you displayed is an array of objects, and each object has the same label and value field. Assuming the other JSON you are referring to shares the same pattern, you only need to create one class with those two properties and parse the JSON into an array of that class.
@Offnix, Well Json.Net allows for dynamics just make sure that the properties you call actually exist in the json or you will get dynamic runtime errors. Otherwise just create a class with the properties you want to use and it will only populate the class with those and ignore the rest
0

Try my answer to this question :

public IEnumerable<MeItem> DeserializeListFromJson(string jsonArray)
{
    return JsonConverter.DeserializeObject<List<JObject>>(jsonArray).Select( obj => DeserializeFromJson(obj) );
}

public MeItem DeserializeFromJson(string jsonString)
{
    return JsonConvert.DeserializeObject<MeItem>(jsonString);
}

You can find necessary detailed informations in my answer for this question and this one

Edit:

If you do not want to use classes then you can just modify DeserializeFromJson() method into something like this :

public KeyValuePair<string, string> DeserializeFromJson(JObject obj)
{
    return new KeyValuePair<string, string>(obj.SelectToken("label").Value<string>(), obj.SelectToken("value").Value<string>());
}

Which will require to modify DeserializeListFromJson() method into :

public IEnumerable<KeyValuePair<string,string>> DeserializeListFromJson(string jsonArray)
{
    return JsonConverter.DeserializeObject<List<JObject>>(jsonArray).Select( obj => DeserializeFromJson(obj) );
}

Usage with your case :

Stream stream = client.OpenRead("http://services.runescape.com/m=itemdb_rs/bestiary/beastSearch.json?term=" + Input);
ListViewItem item = null;
using (StreamReader reader = new StreamReader(stream))
{
    KeyValuePair<string, string> selected = DeserializeListFromJson(reader.ReadToEnd()).ElementAt(i);
    item = new ListViewItem(new string[] { selected.Key, selected.Value });
}

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.