JContainer, JObject, JToken and Linq confusion
You don't really need to worry about JContainer
in most cases. It is there to help organize and structure LINQ-to-JSON into well-factored code.
The JToken
hierarchy looks like this:
JToken - abstract base class
JContainer - abstract base class of JTokens that can contain other JTokens
JArray - represents a JSON array (contains an ordered list of JTokens)
JObject - represents a JSON object (contains a collection of JProperties)
JProperty - represents a JSON property (a name/JToken pair inside a JObject)
JValue - represents a primitive JSON value (string, number, boolean, null)
So you see, a JObject
is a JContainer
, which is a JToken
.
Here's the basic rule of thumb:
- If you know you have an object (denoted by curly braces
{
and}
in JSON), useJObject
- If you know you have an array or list (denoted by square brackets
[
and]
), useJArray
- If you know you have a primitive value, use
JValue
- If you don't know what kind of token you have, or want to be able to handle any of the above in a general way, use
JToken
. You can then check itsType
property to determine what kind of token it is and cast it appropriately.
JContainer
is a base class for JSON elements that have child items. JObject
, JArray
, JProperty
and JConstructor
all inherit from it.
For example, the following code:
(JObject)JsonConvert.DeserializeObject("[1, 2, 3]")
Would throw an InvalidCastException
, but if you cast it to a JContainer
, it would be fine.
Regarding your original question, if you know you have a JSON object at the top level, you can just use:
var jsonWork = JObject.Parse(json);
var jsonObject1 = jsonWork["Object1"];