JContainer, JObject, JToken and Linq confusion JContainer, JObject, JToken and Linq confusion json json

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"];


Most examples have simple json and I've googled "C# Newtonsoft parse JSON" more than once.

Here's a bit of a json file I was just asked to parse for a csv. The company name value is nested within many arrays / objects so it is semi-complicated in that regard.

{  "page": {    "page": 1,    "pageSize": 250  },  "dataRows": [    {      "columnValues": {        "companyName": [          {            "name": "My Awesome Company",          }        ]      }    }  ]}
            var jsonFilePath = @"C:\data.json";            var jsonStr = File.ReadAllText(jsonFilePath);            // JObject implementation for getting dataRows JArray - in this case I find it simpler and more readable to use a dynamic cast (below)            //JObject jsonObj = JsonConvert.DeserializeObject<JObject>(jsonStr);            //var dataRows = (JArray)jsonObj["dataRows"];            var dataRows = ((dynamic)JsonConvert.DeserializeObject(jsonStr)).dataRows;            var csvLines = new List<string>();            for (var i = 0; i < dataRows.Count; i++)            {                var name = dataRows[i]["columnValues"]["companyName"][0]["name"].ToString();                // dynamic casting implemntation to get name - in this case, using JObject indexing (above) seems easier                //var name2 = ((dynamic)((dynamic)((dynamic)dataRows[i]).columnValues).companyName[0]).name.ToString();                csvLines.Add(name);            }            File.WriteAllLines($@"C:\data_{DateTime.Now.Ticks}.csv", csvLines);