From 81524b0ffb079c726ddb00cb6df4db80d0b407c6 Mon Sep 17 00:00:00 2001 From: zcher Date: Sun, 14 Dec 2025 18:15:23 +0300 Subject: [PATCH] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D1=8C=D1=82?= =?UTF-8?q?=D0=B5=20=D1=84=D0=B0=D0=B9=D0=BB=D1=8B=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B5=D0=BA=D1=82=D0=B0.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ContactsApp.csproj | 14 +++++ ContactsApp.http | 6 +++ ContactsApp.slnx | 3 ++ Controllers/ContactController.cs | 90 +++++++++++++++++++++++++++++++ IContactRepository.cs | 16 ++++++ Models/Contact.cs | 33 ++++++++++++ Program.cs | 32 +++++++++++ Properties/launchSettings.json | 15 ++++++ Repositories/ContactRepository.cs | 64 ++++++++++++++++++++++ appsettings.Development.json | 8 +++ appsettings.json | 9 ++++ 11 files changed, 290 insertions(+) create mode 100644 ContactsApp.csproj create mode 100644 ContactsApp.http create mode 100644 ContactsApp.slnx create mode 100644 Controllers/ContactController.cs create mode 100644 IContactRepository.cs create mode 100644 Models/Contact.cs create mode 100644 Program.cs create mode 100644 Properties/launchSettings.json create mode 100644 Repositories/ContactRepository.cs create mode 100644 appsettings.Development.json create mode 100644 appsettings.json diff --git a/ContactsApp.csproj b/ContactsApp.csproj new file mode 100644 index 0000000..fa1439a --- /dev/null +++ b/ContactsApp.csproj @@ -0,0 +1,14 @@ + + + + net10.0 + enable + enable + + + + + + + + diff --git a/ContactsApp.http b/ContactsApp.http new file mode 100644 index 0000000..0a549e4 --- /dev/null +++ b/ContactsApp.http @@ -0,0 +1,6 @@ +@ContactsApp_HostAddress = http://localhost:5246 + +GET {{ContactsApp_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/ContactsApp.slnx b/ContactsApp.slnx new file mode 100644 index 0000000..cd7d5d3 --- /dev/null +++ b/ContactsApp.slnx @@ -0,0 +1,3 @@ + + + diff --git a/Controllers/ContactController.cs b/Controllers/ContactController.cs new file mode 100644 index 0000000..eb28f93 --- /dev/null +++ b/Controllers/ContactController.cs @@ -0,0 +1,90 @@ +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Diagnostics.HealthChecks; +using System.Text.Json; + +namespace ContactsApp +{ + [ApiController] + [Route("api/contacts")] + public class ContactController(IContactRepository repository) : ControllerBase + { + [HttpGet] + public ActionResult> GetAll() + { + var contacts = repository.GetAll().ToList(); + return Ok(contacts); + } + + [HttpPost] + public ActionResult Create([FromBody] Contact contact) + { + repository.AddContact(contact); + return Ok(contact); + } + + [HttpGet("{id:Guid}")] + public ActionResult GetById(Guid id) + { + var contact = repository.GetContactById(id); + if (contact == null) + return NotFound(); + + return Ok(contact); + } + [HttpPost("{id:Guid}")] + public ActionResult Update(Guid id, [FromBody] Contact contact) + { + repository.UpdateContact(id, contact); + return Ok(); + } + + [HttpDelete("{id:Guid}")] + public ActionResult Delete(Guid id) + { + var contact = repository.GetContactById(id); + if (contact == null) + return NotFound(); + + repository.DeleteContact(id); + return Ok(); + } + + [HttpPost("upload")] + public async Task Upload(IFormFile file) + { + if (file == null || file.Length == 0) + return BadRequest("Файл пустой."); + + using var stream = new MemoryStream(); + await file.CopyToAsync(stream); + string json = System.Text.Encoding.UTF8.GetString(stream.ToArray()); + + try + { + repository.LoadJSON(json); // репозиторий сам парсит JSON и обновляет список + } + catch (Exception ex) + { + return BadRequest("Ошибка при обработке JSON: " + ex.Message); + } + + return Ok("Контакты успешно загружены."); + } + + [HttpGet("download")] + public IActionResult Download() + { + string json = repository.SaveJSON(); // репозиторий формирует JSON строку + byte[] bytes = System.Text.Encoding.UTF8.GetBytes(json); + + return File( + bytes, + "application/json", + "contacts.json" + ); + } + + } +} + + diff --git a/IContactRepository.cs b/IContactRepository.cs new file mode 100644 index 0000000..230ae69 --- /dev/null +++ b/IContactRepository.cs @@ -0,0 +1,16 @@ +п»їusing System; +using System.Threading.Tasks; + +namespace ContactsApp +{ + public interface IContactRepository + { + public void AddContact(Contact contact); + public void UpdateContact(Guid id, Contact contact); + public void DeleteContact(Guid id); + public Contact GetContactById(Guid id); + public IEnumerable GetAll(); + public void LoadJSON(string file); + public string SaveJSON(); + } +} diff --git a/Models/Contact.cs b/Models/Contact.cs new file mode 100644 index 0000000..c718597 --- /dev/null +++ b/Models/Contact.cs @@ -0,0 +1,33 @@ +using System.ComponentModel.DataAnnotations; +using System.Net.Mail; + +namespace ContactsApp +{ + public class Contact + { + public Guid Id { get; } + public string Name { get; set; } + public string? Email { get; set; } + public string Phone { get; set; } + + public Contact(string name, string? email, string phone) + { + Id = Guid.NewGuid(); + Name = name; + + try + { + var addr = new MailAddress(email); + Email = email; + } + catch (Exception ex) + { + throw new Exception("Invalid email"); + } + + Phone = phone; + } + } +} + + diff --git a/Program.cs b/Program.cs new file mode 100644 index 0000000..8bf2641 --- /dev/null +++ b/Program.cs @@ -0,0 +1,32 @@ +using Microsoft.AspNetCore.Mvc; +using Swashbuckle.AspNetCore.Swagger; + + +namespace ContactsApp; + +public class Program +{ + public static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); + + // Add services to the container. + builder.Services.AddControllers(); + builder.Services.AddAuthorization(); + builder.Services.AddSwaggerGen(); + + builder.Services.AddSingleton(); + + var app = builder.Build(); + + // Configure the HTTP request pipeline. + // Запрос -> Компу -> По порту -> Приложение -> Kestrel -> (HttpContext) Middlewares -> Controller (mapping) -> AfterMethod -> Method -> BeforeMethod + app.UseAuthorization(); + app.UseSwagger(); + app.UseSwaggerUI(); + + + app.MapControllers(); + app.Run(); + } +} \ No newline at end of file diff --git a/Properties/launchSettings.json b/Properties/launchSettings.json new file mode 100644 index 0000000..883ff9b --- /dev/null +++ b/Properties/launchSettings.json @@ -0,0 +1,15 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": false, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5043", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Repositories/ContactRepository.cs b/Repositories/ContactRepository.cs new file mode 100644 index 0000000..c8e8823 --- /dev/null +++ b/Repositories/ContactRepository.cs @@ -0,0 +1,64 @@ +п»їusing Microsoft.Win32; +using System; +using System.Runtime; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace ContactsApp +{ + public class ContactRepository : IContactRepository + { + List Contacts = new (); + + + public void AddContact(Contact contact) + { + CheckUnique(contact); + Contacts.Add(contact); + } + + public void UpdateContact(Guid id, Contact contact) + { + CheckUnique(contact); + Contact previous = GetContactById(id); + if (previous == null) + { + Contacts.Add(contact); + return; + } + + previous.Name = contact.Name; + previous.Email = contact.Email; + previous.Phone = contact.Phone; + } + + public void DeleteContact(Guid id) + { + var contact = GetContactById(id); + if (contact == null) + return; + Contacts.Remove(contact); + } + + public Contact GetContactById(Guid id) + { + return Contacts.Find(x => x.Id == id); + } + public void LoadJSON(string json) + { + var list = JsonSerializer.Deserialize>(json); + Contacts.AddRange(list); + } + public string SaveJSON() + { + return JsonSerializer.Serialize(Contacts, new JsonSerializerOptions { WriteIndented = true }); + } + + public IEnumerable GetAll() => Contacts; + private void CheckUnique(Contact contact) + { + if (Contacts.FirstOrDefault(x => x.Equals(contact)) != null) + throw new Exception("Такой контакт СѓР¶Рµ есть"); + } + } +} diff --git a/appsettings.Development.json b/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/appsettings.json b/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +}