Deserialize JSON to Dynamic Object Using Newtonsoft.Json in C#
By Tan Lee Published on Jan 21, 2025 610
Consider this JSON data:
{ "name": "Alice", "preferences": { "color": "blue", "animal": "dog" } }
To deserialize this JSON into a dynamic object with Newtonsoft.Json, use JsonConvert.DeserializeObject<dynamic>
as shown below:
using Newtonsoft.Json; var person = JsonConvert.DeserializeObject<dynamic>(json); Console.WriteLine($"{person.name}'s favorite color is {person.preferences.color}"); Console.WriteLine($"{person.name}'s favorite animal is {person.preferences.animal}");
This will output:
Alice's favorite color is blue Alice's favorite animal is dog
Deserialize JSON to ExpandoObject
In versions of Newtonsoft.Json prior to v4.0.1 (released in 2014), using dynamic
would lead to an exception. In these older versions, you should deserialize to an ExpandoObject
using the ExpandoObjectConverter
.
using Newtonsoft.Json; using Newtonsoft.Json.Converters; dynamic config = JsonConvert.DeserializeObject<ExpandoObject>(json, new ExpandoObjectConverter());
Deserialize JSON Array to Dynamic Object
Let’s say you are working with JSON that contains an array of objects, like this:
{ "version": 2.0, "servers": [ { "name": "web", "status": "active" }, { "name": "db", "status": "inactive" }, { "name": "cache", "status": "active" } ] }
To deserialize this into a dynamic object, you can loop over the array like this:
using Newtonsoft.Json; var config = JsonConvert.DeserializeObject<dynamic>(json); Console.WriteLine($"Using API version: {config.version}"); foreach (var server in config.servers) { Console.WriteLine($"{server.name} status: {server.status}"); }
Output:
Using API version: 2 web status: active db status: inactive cache status: active
Filtering with LINQ
If you want to filter the array using LINQ, you can cast it to IEnumerable<dynamic>
first.
For example, to list only the active servers:
using System.Linq; Console.WriteLine("Active servers:"); foreach (var activeServer in ((IEnumerable<dynamic>)config.servers).Where(s => s.status == "active")) { Console.WriteLine($"{activeServer.name}"); }
Output:
Active servers: web cache
System.Text.Json vs. Newtonsoft.Json
The built-in System.Text.Json library doesn’t handle dynamic deserialization as smoothly as Newtonsoft.Json.
For example:
dynamic config = System.Text.Json.JsonSerializer.Deserialize<dynamic>(json);
When deserializing to a dynamic object, System.Text.Json returns a JsonElement
instead. While you can work with JsonElement
for JSON Document Model tasks, this doesn't give you true dynamic object behavior. If you need dynamic support, Newtonsoft.Json is the better option.
If you got an error:
InvalidCastException: Unable to cast object of type ‘System.Collections.Generic.List`1[System.Object]’ to type ‘System.Dynamic.ExpandoObject’.
For example:
if (response.IsSuccessStatusCode) { var data = await response.Content.ReadAsStringAsync(); dynamic config = JsonConvert.DeserializeObject<ExpandoObject>(data, new ExpandoObjectConverter()); }
It seems you're deserializing a JSON array.
Instead of using ExpandoObject
, use IEnumerable<ExpandoObject>
as the type parameter, like this:
if (response.IsSuccessStatusCode) { var data = await response.Content.ReadAsStringAsync(); dynamic config = JsonConvert.DeserializeObject<IEnumerable<ExpandoObject>>(data, new ExpandoObjectConverter()); }