> Как обрабатывать JSON объекты из файла с одинаковыми элементами (C# /.NET)
Уровень: senior · Роль: backend · Категория: Технические вопросы
Компании: Ozon
Стек: C# /.NET
> Пример ответа
При работе с JSON, содержащим дублирующиеся ключи, стандартные десериализаторы (например, System.Text.Json или Newtonsoft.Json) по умолчанию выбрасывают исключение или берут последнее значение. Чтобы корректно обработать такие данные, нужно использовать кастомные стратегии.1. Использование JsonDocument (System.Text.Json):
Позволяет вручную обойти все элементы и собрать дубликаты в коллекцию.
CSHARPusing System.Text.Json;string json = File.ReadAllText("data.json");using JsonDocument doc = JsonDocument.Parse(json);JsonElement root = doc.RootElement;var duplicates = new Dictionary<string, List<JsonElement>>();foreach (var property in root.EnumerateObject()){if (!duplicates.ContainsKey(property.Name))duplicates[property.Name] = new List<JsonElement>();duplicates[property.Name].Add(property.Value);}
2. Кастомный конвертер для Dictionary<string, List<T>>:
Если нужно десериализовать в строго типизированную модель, напишите конвертер, который собирает все значения для одного ключа в список.
CSHARPpublic class DuplicateKeyConverter<T> : JsonConverter<Dictionary<string, List<T>>>{public override Dictionary<string, List<T>> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options){var result = new Dictionary<string, List<T>>();while (reader.Read()){if (reader.TokenType == JsonTokenType.PropertyName){string key = reader.GetString();reader.Read();var value = JsonSerializer.Deserialize<T>(ref reader, options);if (!result.ContainsKey(key))result[key] = new List<T>();result[key].Add(value);}else if (reader.TokenType == JsonTokenType.EndObject)break;}return result;}// Write - не требуется для чтения}
3. Обработка на уровне JObject (Newtonsoft.Json):
Используйте JsonLoadSettings с флагом DuplicatePropertyNameHandling.
CSHARPvar settings = new JsonLoadSettings { DuplicatePropertyNameHandling = DuplicatePropertyNameHandling.Replace };JObject obj = JObject.Parse(File.ReadAllText("data.json"), settings);// Теперь дубликаты заменяются последним значением, но можно и игнорировать
Рекомендация: Если дубликаты - это ошибка данных, лучше валидировать JSON перед обработкой. Если же это допустимая структура (например, логи), используйте JsonDocument для потокового чтения без загрузки всего файла в память.
> Похожие задачи по backend
Что такое метаклассы в Python и для чего они используются
В чем разница между словарем Python и форматом данных JSON
Как вернуть только что вставленную строку в базе данных
Как решить проблему race condition и какие механизмы синхронизации использовать в Java
> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?
Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью