Как десериализовать JSON в динамический объект в C#?
Использование Newtonsoft.Json (Json.NET)
Самый популярный способ — использовать Newtonsoft.Json. Он поддерживает динамические объекты через тип JObject или напрямую через dynamic с помощью метода JsonConvert.DeserializeObject.
Способ 1: Через dynamic
Просто укажите dynamic как целевой тип:
using Newtonsoft.Json;
string json = @"{""name"": ""John"", ""age"": 30}";
dynamic obj = JsonConvert.DeserializeObject(json);
Console.WriteLine(obj.name); // John
Console.WriteLine(obj.age); // 30
Этот метод автоматически создаёт JObject или JArray в зависимости от JSON. Вы можете обращаться к свойствам через точку, как к обычным объектам.
Способ 2: Через JObject
Если нужен более строгий контроль, используйте JObject.Parse:
using Newtonsoft.Json.Linq;
string json = @"{""name"": ""John"", ""age"": 30}";
JObject obj = JObject.Parse(json);
Console.WriteLine(obj["name"]); // John
Console.WriteLine(obj["age"]); // 30
JObject позволяет работать с вложенными структурами:
string json = @"{""address"": {""city"": ""Moscow""}}";
JObject obj = JObject.Parse(json);
Console.WriteLine(obj["address"]["city"]); // Moscow
Обработка массивов
Для массивов используйте JArray:
string json = @"{""features"": [""SSD"", ""16GB RAM""]}";
dynamic obj = JsonConvert.DeserializeObject(json);
foreach (var feature in obj.features)
{
Console.WriteLine(feature);
}
Использование System.Text.Json (.NET Core 3.0+)
Встроенная библиотека System.Text.Json не поддерживает dynamic напрямую, но можно использовать JsonDocument для гибкого доступа:
using System.Text.Json;
string json = @"{""name"": ""John"", ""age"": 30}";
using JsonDocument doc = JsonDocument.Parse(json);
JsonElement root = doc.RootElement;
Console.WriteLine(root.GetProperty("name").GetString()); // John
Console.WriteLine(root.GetProperty("age").GetInt32()); // 30
Для вложенных объектов:
string json = @"{""address"": {""city"": ""Moscow""}}";
using JsonDocument doc = JsonDocument.Parse(json);
JsonElement address = doc.RootElement.GetProperty("address");
Console.WriteLine(address.GetProperty("city").GetString()); // Moscow
Рекомендации
- Newtonsoft.Json — лучший выбор для
dynamicи простоты. Установите через NuGet:Install-Package Newtonsoft.Json. - System.Text.Json — быстрее и без внешних зависимостей, но требует больше кода для динамического доступа.
- Если структура JSON известна хотя бы частично, рассмотрите создание классов с
JsonExtensionDataдля неизвестных полей.
Пример с ExpandoObject (альтернатива):
using Newtonsoft.Json;
using System.Dynamic;
string json = @"{""name"": ""John""}";
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(json);
Console.WriteLine(obj.name);
Этот метод даёт полностью динамический объект, к которому можно добавлять свойства на лету.
<<Альтернативный подход: Использование словарей и рефлексии
Если вы не хотите подключать Newtonsoft.Json или работать с dynamic, можно десериализовать JSON в Dictionary<string, object> и обращаться к полям по ключу. Это даёт полный контроль без неявных преобразований.
Пример с System.Text.Json
using System.Text.Json;
string json = @"{""name"": ""John"", ""age"": 30}";
var dict = JsonSerializer.Deserialize<Dictionary<string, object>>(json);
Console.WriteLine(dict["name"]); // John
Для вложенных объектов нужно рекурсивно обрабатывать JsonElement:
string json = @"{""address"": {""city"": ""Moscow""}}";
var doc = JsonDocument.Parse(json);
var dict = new Dictionary<string, object>();
foreach (var prop in doc.RootElement.EnumerateObject())
{
dict[prop.Name] = prop.Value;
}
Console.WriteLine(dict["address"]); // { "city": "Moscow" }
Плюсы и минусы
- Плюсы: Безопасность типов (нет риска опечаток в именах свойств), поддержка всех версий .NET.
- Минусы: Больше кода, нет синтаксиса через точку, сложнее работать с массивами.
Этот подход хорош, когда JSON имеет фиксированную, но неизвестную структуру, и вы хотите избежать лишних зависимостей.
Ответов пока нет.
Войдите чтобы оставить ответ