0

I have been working with newtonsoft api for a while now. From the terminology point of view, it makes sense when you call out a value of a property you will get a JValue. But do I continue processing that value if it is a JObject? The only way that I have come up is to call out: JObject.Parse(JValue.ToString())

A cast would trigger an InvalidCastException.

I hope that someone could provide me an example of how to handle nested JObjects.

badbyte
  • 83
  • 1
  • 10
  • A JValue can't be JObject - one does not inherit from the other. A property in JSON.net is a string / JToken pair. So you are probably getting back a JToken? JToken is a common ancestor of both JValue and JObject. – James Gaunt Aug 06 '19 at 11:31
  • You may benefit from [this answer](https://stackoverflow.com/a/38560188/10263), which describes the `JToken` hierarchy. – Brian Rogers Aug 06 '19 at 14:56

2 Answers2

2

enter image description here

If you look at the API of JObject

https://www.newtonsoft.com/json/help/html/T_Newtonsoft_Json_Linq_JObject.htm

You can see that when you access a property it returns a JToken, not a JValue.

A JToken is a common ancestor of both JValue and JObject so you'd just cast after checking which it is (e.g. using the is operator). Note it could also by a JArray (which is neither a JValue or a JObject).

Wyck
  • 10,311
  • 6
  • 39
  • 60
James Gaunt
  • 14,631
  • 2
  • 39
  • 57
  • Looking at the watch window, I get a JValue and not JToken. – badbyte Aug 07 '19 at 13:15
  • 1
    I assume that is telling you the return type is a JToken but the instance type is JValue which is possible. But if the property is actually a JObject you'd get "Newtonsoft... JToken (Newtonsoft... JObject)" instead.When looking at the watch window you're obviously seeing the actual instances, not the signature. It's just that you can't cast direct from JValue to JObject. The property value accessor returns a JToken as you can see in the linked API docs. So capture that, determine what it really is, and cast upwards. – James Gaunt Aug 08 '19 at 12:10
1

This is probably obvious but was a gotcha for me that might help someone.

If I have a JObject containing another object called "myProperty" and I retrieve it like this:

var myResult = jobject["myProperty"] // myResult is a JValue

myResult is a JValue.

If I want a JObject I need to:

var myJObjectResult = jobject["myProperty"].Value<JObject>()
mcmcmc
  • 189
  • 2
  • 8