Deserialize JSON to Dynamic Object Using Newtonsoft.Json in C#
By FoxLearn 3/21/2025 2:09:29 AM 474
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()); }
- Primitive types in C#
- How to set permissions for a directory in C#
- How to Convert Int to Byte Array in C#
- How to Convert string list to int list in C#
- How to convert timestamp to date in C#
- How to Get all files in a folder in C#
- How to use Channel as an async queue in C#
- Case sensitivity in JSON deserialization