Вопрос или проблема
Я использую System.Text.Json.
У меня есть следующие модели:
public class Contacts
{
[JsonPropertyName("id")]
public long Id { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; } = string.Empty;
[JsonPropertyName("paused")]
public bool Paused { get; set; }
[JsonPropertyName("type")]
public string Type { get; set; } = string.Empty;
[JsonPropertyName("owner")]
public bool Owner { get; set; }
[JsonPropertyName("notification_targets")]
public NotificationTargets? NotificationTargets { get; set; }
[JsonPropertyName("teams")]
public List<Teams>? Teams { get; set; }
}
public class NotificationTargets
{
[JsonPropertyName("email")]
public List<Email>? Email { get; set; }
}
public class Email
{
[JsonPropertyName("severity")]
public string Severity { get; set; } = string.Empty;
[JsonPropertyName("address")]
public string Address { get; set; } = string.Empty;
}
public class Teams
{
[JsonPropertyName("id")]
public long Id { get; set; }
[JsonPropertyName ("name")]
public string Name { get; set; } = string.Empty;
}
Мой JSON:
{
"contacts": [
{
"id": 14960844,
"name": "firstname test",
"paused": false,
"type": "user",
"owner": true,
"notification_targets": {
"email": [
{
"severity": "HIGH",
"address": "[email protected]"
}
]
},
"teams": [
{
"id": 804736,
"name": "Team 1"
}
]
}
]
}
Это хранится в строковой переменной.
И я просто вызываю:
var myContacts = JsonSerializer.Deserialize<List<Contacts>>(myJsonString);
И я продолжаю получать следующую ошибку:
System.Text.Json.JsonException: ‘JSON значение не может быть преобразовано
в System.Collections.Generic.List`1[VTMShared.Models.Contacts]. Путь:
$ | НомерСтроки: 0 | ПозицияБайтаВСтроке: 1.’
Я действительно не вижу, что с этим не так.
Вам нужно десериализовать как Root
и извлечь Contacts
из экземпляра Root
.
var root = JsonSerializer.Deserialize<Root>(json);
var contacts = root.Contacts;
public class Root
{
[JsonPropertyName("contacts")]
public List<Contact> Contacts { get; set; }
}
public class Contact
{
[JsonPropertyName("id")]
public long Id { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; } = string.Empty;
[JsonPropertyName("paused")]
public bool Paused { get; set; }
[JsonPropertyName("type")]
public string Type { get; set; } = string.Empty;
[JsonPropertyName("owner")]
public bool Owner { get; set; }
[JsonPropertyName("notification_targets")]
public NotificationTargets? NotificationTargets { get; set; }
[JsonPropertyName("teams")]
public List<Teams>? Teams { get; set; }
}
Без определения класса Root
вы можете работать с JsonDocument
:
var root = JsonDocument.Parse(json);
var contacts = root.RootElement.GetProperty("contacts").Deserialize<List<Contact>>();
Вы можете использовать другой класс Root
для десериализации всего JSON, но также вы можете попробовать сделать это без root – тогда это можно разобрать в словарь с одним элементом:
var myContactsDict = JsonSerializer.Deserialize<Dictionary<string, List<Contacts>>>(myJsonString);
var myContacts = myContactsDict["contacts"];
Ответ или решение
Ваша проблема с десериализацией JSON связана с тем, что вы пытаетесь десериализовать объект List<Contacts>
, однако предоставленный JSON представляет собой объект с корневым свойством "contacts", которое является списком. Поэтому вам необходимо создать дополнительный класс для корневого объекта или извлечь данные непосредственно из JSON. Давайте рассмотрим оба подхода.
1. Использование класса Root
Для начала создадим класс Root
, который будет представлять корневой объект вашего JSON:
public class Root
{
[JsonPropertyName("contacts")]
public List<Contacts> Contacts { get; set; }
}
Теперь вы можете десериализовать JSON следующим образом:
var root = JsonSerializer.Deserialize<Root>(myJsonString);
var contacts = root.Contacts;
Этот метод является самым удобным, так как сохраняет типизацию и делает код более читаемым.
2. Использование JsonDocument
Если вы не хотите создавать отдельный класс для корневого объекта, вы можете десериализовать JSON в JsonDocument
и извлечь нужные данные оттуда:
using System.Text.Json;
var root = JsonDocument.Parse(myJsonString);
var contacts = root.RootElement.GetProperty("contacts").Deserialize<List<Contacts>>();
Этот подход позволяет работать с JSON напрямую, но может быть менее удобным из-за необходимости манипулировать элементами и отсутствия строгой типизации.
3. Десериализация через коллекцию словарей
Еще один подход заключается в том, чтобы использовать Dictionary
, где ключом будет строка, а значением — список Contacts
:
var myContactsDict = JsonSerializer.Deserialize<Dictionary<string, List<Contacts>>>(myJsonString);
var myContacts = myContactsDict["contacts"];
Этот метод также корректно извлечет ваши данные, хотя и потребует более сложного обращения с типами.
Итоги
В вашем случае самым простым и понятным решением будет использование класса Root
, однако альтернативные методы также доступны, в зависимости от контекста вашей задачи. Не забудьте удостовериться, что ваш JSON соответствует ожидаемым свойствам в классах, чтобы избежать ошибок десериализации.