C# Deserialize JSON to Dynamic Object Using Newtonsoft.Json
By FoxLearn 1/21/2025 4:29:40 AM 290
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()); }
- Using the OrderBy and OrderByDescending in LINQ
- Querying with LINQ
- Optimizing Performance with Compiled Queries in LINQ
- MinBy() and MaxBy() Extension Methods in .NET
- SortBy, FilterBy, and CombineBy in NET 9
- Exploring Hybrid Caching in .NET 9.0
- Using Entity Framework with IDbContext in .NET 9.0
- Primitive types in C#