1

I have the following JSON

{ "nest1" : { "attributes" : { "type" : "irrelevant", "url" : "irrelevant" }, "key" : "value1" }, "nest2" : { "attributes" : { "type" : "irrelevant", "url" : "irrelevant" }, "key" : "value2" } } 

I have tried something like below to grab the value for the secondkey, but this throws an InvalidOperationException. with the following error message:

Cannot access child value on Newtonsoft.Json.Linq.JProperty.

string value = getJson(json, "key"); 

The method looks like

public string getJson(string json, string name) { JObject token = JObject.Parse(json); JToken jtoken = token.Last.ToString(); return jtoken[name].toString(); } 

I'm guessing there is probably something simple i'm forgetting, any help would be great

2
  • You know that the [...] at the start and end are largely unnecessary, right? You're creating an extra array that contains one object that contains multiple keyed objects. Your JSON structure needs a bit of cleanup. Commented Jun 6, 2012 at 19:26
  • Yeah I parse that out, wasn't suppose to put that in there. Thanks. Commented Jun 6, 2012 at 19:30

3 Answers 3

2

There are two problems with your code:

  1. You're using ToString() incorrectly. If you implicitly convert a string to JToken like you do, the resulting JToken contains the text, not the object the string represents. So you should get rid of the call to ToString().
  2. Last doesn't return the value of nest2, it returns the whole property. To get just the value of the last property, you can use something like token.PropertyValues().Last().

So, your code could look like this:

public static string GetJson(string json, string name) { JObject obj = JObject.Parse(json); JToken lastValue = obj.PropertyValues().Last(); return lastValue[name].Value<string>(); } 

I have also changed the last ToString() to Value<string>(), because I think it makes more sense here, even though it doesn't change the result.

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

3 Comments

I think writing code depending on the order of properties ( Last() ) should be something to avoid.
@L.B Probably, yeah. But that's what was in the question and doing something else would mean I would have to guess what is the code actually meant to do and what are the possible inputs.
@LB you're probably right. Although i don't believe the order will ever change from the JSON I'm receiving, this seems to be the only way to pick out that value without deserializing
2
dynamic dynObj = JsonConvert.DeserializeObject(json); foreach (var item in dynObj) { foreach (var subitem in item) { Console.WriteLine("url:" + subitem.attributes.url); Console.WriteLine("key:" + subitem.key); } } 

6 Comments

I'm not sure how will dynamic actually help here (apart from making the syntax a bit nicer).
This doesn't compile for me, doesn't like doing a foreach on the dynObj
@AdamSweeney It works for me. What compilation error do you get?
foreach statement cannot operate on variables of type 'System.Collection.IEnumerable' because 'System.Collections.IEnumerable` does not contain a public definition for 'GetEnumberator'
Strange. My conf: VS2010 + .Net 4.0 + Json.Net 4.5
|
0

Maybe you have a misconception. In this case there are two a principal object that have two properties:

Principal { var1; var2 } 

Same thing to the properties. Do you need a array of objects?

[ { "objects" : [ { "attributes" : { "type" : "irrelevant", "url" : "irrelevant" }, "key" : "value1" }, { "attributes" : { "type" : "irrelevant", "url" : "irrelevant" }, "key" : "value2" } ] } ] 

1 Comment

I don't have any control over the JSON, it's just what I get as a response

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.