JSON часто встречается раньше базы данных: настройки проекта, ответ API, локальный файл с данными, конфиг для урока. В C# для работы с JSON есть встроенный System.Text.Json, а для чтения файлов — System.IO.File. В этом уроке мы прочитаем config.json, превратим его в C#-объект и запишем обновленную копию обратно
Главная цель: не собирать JSON строками и не парсить его вручную
Что получится в конце
У нас будет файл config.json:
{
"projectName": "CSharpJsonDemo",
"maxItems": 10,
"enableCache": true
}
Программа выведет:
Проект: CSharpJsonDemo
Лимит: 10
Кеш включен: True
Создаем проект
dotnet new console -n CSharpJsonFiles
cd CSharpJsonFiles
Создайте рядом с Program.cs файл config.json:
{
"projectName": "CSharpJsonDemo",
"maxItems": 10,
"enableCache": true
}
Читаем JSON
Вставьте в Program.cs:
using System.Text.Json;
var json = File.ReadAllText("config.json");
var config = JsonSerializer.Deserialize<AppConfig>(json);
if (config is null)
{
Console.WriteLine("Не удалось прочитать config.json");
return;
}
Console.WriteLine($"Проект: {config.ProjectName}");
Console.WriteLine($"Лимит: {config.MaxItems}");
Console.WriteLine($"Кеш включен: {config.EnableCache}");
public class AppConfig
{
public string ProjectName { get; set; } = "";
public int MaxItems { get; set; }
public bool EnableCache { get; set; }
}
Запустите:
dotnet run
Почему свойства называются иначе
В JSON поле называется projectName, а в C# свойство — ProjectName. По умолчанию System.Text.Json в web-сценариях часто использует camelCase, но в обычной консольной программе лучше явно задать настройки, чтобы пример был предсказуемым
Измените десериализацию:
var options = new JsonSerializerOptions
{
PropertyNameCaseInsensitive = true
};
var config = JsonSerializer.Deserialize<AppConfig>(json, options);
Теперь сопоставление станет нечувствительным к регистру. Для учебного конфига этого достаточно
Записываем JSON обратно
Добавьте после вывода:
config.MaxItems = 25;
var outputJson = JsonSerializer.Serialize(config, new JsonSerializerOptions
{
WriteIndented = true
});
File.WriteAllText("config.updated.json", outputJson);
После запуска появится файл config.updated.json. WriteIndented = true делает JSON читаемым, с переносами и отступами
Когда нужен async-вариант
Для маленького файла File.ReadAllText нормально подходит в учебном примере. В серверном приложении или при крупных файлах лучше смотреть в сторону асинхронных методов:
var json = await File.ReadAllTextAsync("config.json");
Но не усложняйте первый пример. Сначала важно понять модель: файл -> строка JSON -> объект C# -> измененный объект -> файл
Частые ошибки
FileNotFoundException. Файл лежит не там, где запускается приложение. Проверьте текущую папку и имя файла
JsonException. JSON сломан: лишняя запятая, неправильные кавычки, незакрытая скобка
Свойства остались пустыми. Имена JSON-полей не сопоставились со свойствами C#. Проверьте регистр или добавьте настройки сериализации
Nullability warning после Deserialize. Deserialize может вернуть null. Проверка if (config is null) здесь не лишняя
Что может быть еще интересно по этой теме
System.Text.Json или Newtonsoft.Json? Для новых учебных проектов начинайте с System.Text.Json: он встроен в современный .NET. Newtonsoft.Json по-прежнему встречается в старых и сложных проектах
Можно ли читать JSON прямо в Dictionary? Можно, но для настроек обычно удобнее класс: свойства видны компилятору, меньше опечаток
Где хранить реальные настройки приложения? В ASP.NET Core обычно используют appsettings.json и configuration API. Этот урок показывает базовую механику
Нужно ли обрабатывать все ошибки JSON? В пользовательском приложении да. В учебном примере достаточно увидеть, где возникают FileNotFoundException и JsonException
Что открыть дальше
- async await в C#: первый пример без магии — чтобы перейти к
ReadAllTextAsync. - ASP.NET Core Minimal API: первый endpoint — JSON станет HTTP-ответом.
- Классы и свойства в C#: первый пример —
AppConfigпостроен на обычном классе. - Ошибки C#: cannot convert, null reference и missing using — пригодится при работе с файлами и nullable.



