/
dOJer113
/
Insect
Обзор
Документация
Войти
/
dOJer113
/
Insect
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
Server/InsectRepository.cs
263 строки
8 KB
alex
Валидация
21 дек 2025, 20:06
21 дек 2025, 20:06
640f9dc
Код
Авторство
О чём код?
using System.Text.Json; using insects; using System.Text.Encodings.Web; using System.Text.Unicode; namespace InsectServer; public class InsectValidationResult { public bool IsValid { get; set; } public List<string> ErrorMessages { get; set; } = new(); } public class InsectRepository { private readonly string _filePath; private readonly List<Insect> _insects = new(); private readonly JsonSerializerOptions _jsonOptions; private string? _fileLoadError; private readonly List<string> _validationErrors = new(); public InsectRepository(string filePath) { _filePath = filePath; _jsonOptions = new JsonSerializerOptions { PropertyNameCaseInsensitive = true, PropertyNamingPolicy = JsonNamingPolicy.CamelCase, WriteIndented = true, Encoder = JavaScriptEncoder.Create(UnicodeRanges.All) }; _jsonOptions.Converters.Add(new InsectJsonConverter()); Reload(); } public IReadOnlyList<Insect> GetAll() { Reload(); return _insects.OrderBy(x => x.Id).ToList(); } public Insect? GetById(int id) => _insects.FirstOrDefault(x => x.Id == id); public bool HasFileLoadError => !string.IsNullOrEmpty(_fileLoadError) || _validationErrors.Count > 0; public string? FileLoadErrorMessage { get { if (!string.IsNullOrEmpty(_fileLoadError)) { if (_validationErrors.Count > 0) { return $"{_fileLoadError} Также обнаружены ошибки валидации в {_validationErrors.Count} записях: {string.Join("; ", _validationErrors.Take(5))}"; } return _fileLoadError; } if (_validationErrors.Count > 0) { return $"Обнаружены ошибки валидации в {_validationErrors.Count} записях: {string.Join("; ", _validationErrors.Take(5))}"; } return null; } } public InsectValidationResult Add(Insect insect) { insect.Id = 0; var validation = Validate(insect, isNew: true); if (!validation.IsValid) { return validation; } insect.Id = _insects.Count == 0 ? 1 : _insects.Max(s => s.Id) + 1; _insects.Add(insect); SaveToFile(); return validation; } public InsectValidationResult Update(Insect insect) { var validation = Validate(insect, isNew: false); if (!validation.IsValid) { return validation; } var existing = GetById(insect.Id); if (existing is null) { validation.IsValid = false; validation.ErrorMessages.Add("Насекомое с таким ID не найдено."); return validation; } _insects.Remove(existing); _insects.Add(insect); SaveToFile(); return validation; } public bool Delete(int id) { var insect = GetById(id); if (insect is null) { return false; } _insects.Remove(insect); SaveToFile(); return true; } public (bool isValid, List<string> errors) Reload() { LoadFromFile(); if (HasFileLoadError) { return (false, new List<string> { FileLoadErrorMessage ?? "Файл данных повреждён или недоступен." }); } return (true, new List<string>()); } private InsectValidationResult Validate(Insect insect, bool isNew) { var errors = InsectValidator.Validate(insect, requireId: !isNew); return new InsectValidationResult { IsValid = errors.Count == 0, ErrorMessages = errors }; } private void LoadFromFile() { _fileLoadError = null; _validationErrors.Clear(); if (!File.Exists(_filePath)) { SaveToFile(); return; } try { var json = File.ReadAllText(_filePath); if (string.IsNullOrWhiteSpace(json)) { return; } using var document = JsonDocument.Parse(json); if (document.RootElement.ValueKind != JsonValueKind.Array) { _fileLoadError = $"Файл {_filePath} содержит некорректные данные. Ожидается массив JSON."; Console.WriteLine($"ОШИБКА: {_fileLoadError} Сервер продолжит работу с пустым списком насекомых."); return; } _insects.Clear(); var recordIndex = 0; foreach (var element in document.RootElement.EnumerateArray()) { recordIndex++; try { var parsed = JsonSerializer.Deserialize<Insect>(element.GetRawText(), _jsonOptions); if (parsed is null) { _validationErrors.Add($"Запись #{recordIndex}: не удалось десериализовать объект"); continue; } var validation = InsectValidator.Validate(parsed, requireId: true); if (validation.Count > 0) { var errorMsg = $"Запись #{recordIndex} (ID: {parsed.Id}, Name: {parsed.Name ?? "null"}): {string.Join(", ", validation)}"; _validationErrors.Add(errorMsg); Console.WriteLine($"Запись пропущена из-за ошибок: {errorMsg}"); continue; } _insects.Add(parsed); } catch (JsonException ex) { var errorMsg = $"Запись #{recordIndex}: ошибка парсинга JSON - {ex.Message}"; _validationErrors.Add(errorMsg); Console.WriteLine($"Запись пропущена при загрузке: {errorMsg}"); } catch (NotSupportedException ex) { var errorMsg = $"Запись #{recordIndex}: неподдерживаемый тип - {ex.Message}"; _validationErrors.Add(errorMsg); Console.WriteLine($"Запись пропущена при загрузке: {errorMsg}"); } catch (Exception ex) { var errorMsg = $"Запись #{recordIndex}: неожиданная ошибка - {ex.Message}"; _validationErrors.Add(errorMsg); Console.WriteLine($"Запись пропущена при загрузке: {errorMsg}"); } } } catch (JsonException ex) { _fileLoadError = $"Файл {_filePath} содержит некорректный JSON: {ex.Message}"; Console.WriteLine($"ОШИБКА: {_fileLoadError}"); Console.WriteLine("Сервер продолжит работу с пустым списком насекомых."); _insects.Clear(); } catch (IOException ex) { _fileLoadError = $"Не удалось прочитать файл {_filePath}: {ex.Message}"; Console.WriteLine($"ОШИБКА: {_fileLoadError}"); Console.WriteLine("Сервер продолжит работу с пустым списком насекомых."); _insects.Clear(); } catch (UnauthorizedAccessException ex) { _fileLoadError = $"Нет доступа к файлу {_filePath}: {ex.Message}"; Console.WriteLine($"ОШИБКА: {_fileLoadError}"); Console.WriteLine("Сервер продолжит работу с пустым списком насекомых."); _insects.Clear(); } catch (Exception ex) { _fileLoadError = $"Неожиданная ошибка при чтении файла {_filePath}: {ex.Message}"; Console.WriteLine($"ОШИБКА: {_fileLoadError}"); Console.WriteLine("Сервер продолжит работу с пустым списком насекомых."); _insects.Clear(); } } private void SaveToFile() { try { var directory = Path.GetDirectoryName(_filePath); if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory)) { Directory.CreateDirectory(directory); } var json = JsonSerializer.Serialize(_insects, _jsonOptions); File.WriteAllText(_filePath, json); _fileLoadError = null; _validationErrors.Clear(); } catch (Exception ex) { throw new InvalidOperationException($"Не удалось сохранить данные: {ex.Message}", ex); } } }