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), use JObject
  • If you know you have an array or list (denoted by square brackets [ and ]), use JArray
  • 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 its Type 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"];