From fdaad444fe43aba4dc78f8339af98b5bcbd1e797 Mon Sep 17 00:00:00 2001 From: malimova Date: Wed, 1 May 2024 16:23:23 +0400 Subject: [PATCH] =?UTF-8?q?+restapi,=20=D1=82=D0=BE=D0=BB=D1=8C=D0=BA?= =?UTF-8?q?=D0=BE=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BA=D0=B0=20=D0=BA=D0=B0?= =?UTF-8?q?=D0=BA=D0=B0=D1=8F-=D1=82=D0=BE=20=D0=B4=D1=83=D1=80=D0=B0?= =?UTF-8?q?=D1=86=D0=BA=D0=B0=D1=8F,=20=D0=BF=D0=BE=D1=82=D0=BE=D0=BC=20?= =?UTF-8?q?=D0=B3=D0=BB=D1=8F=D0=BD=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Confectionery/Confectionery.sln | 10 +- .../ConfectioneryBusinessLogic/ClientLogic.cs | 123 ++++++++++++++++++ .../ClientStorage.cs | 2 +- .../ConfectioneryRestApi.csproj | 19 +++ .../ConfectioneryRestApi.http | 6 + .../Controllers/WeatherForecastController.cs | 33 +++++ Confectionery/ConfectioneryRestApi/Program.cs | 39 ++++++ .../Properties/launchSettings.json | 41 ++++++ .../ConfectioneryRestApi/WeatherForecast.cs | 13 ++ .../appsettings.Development.json | 8 ++ .../ConfectioneryRestApi/appsettings.json | 9 ++ 11 files changed, 300 insertions(+), 3 deletions(-) create mode 100644 Confectionery/ConfectioneryBusinessLogic/ClientLogic.cs create mode 100644 Confectionery/ConfectioneryRestApi/ConfectioneryRestApi.csproj create mode 100644 Confectionery/ConfectioneryRestApi/ConfectioneryRestApi.http create mode 100644 Confectionery/ConfectioneryRestApi/Controllers/WeatherForecastController.cs create mode 100644 Confectionery/ConfectioneryRestApi/Program.cs create mode 100644 Confectionery/ConfectioneryRestApi/Properties/launchSettings.json create mode 100644 Confectionery/ConfectioneryRestApi/WeatherForecast.cs create mode 100644 Confectionery/ConfectioneryRestApi/appsettings.Development.json create mode 100644 Confectionery/ConfectioneryRestApi/appsettings.json diff --git a/Confectionery/Confectionery.sln b/Confectionery/Confectionery.sln index 16e194e..fd151f3 100644 --- a/Confectionery/Confectionery.sln +++ b/Confectionery/Confectionery.sln @@ -13,9 +13,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryListImplement" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryView", "ConfectioneryView\ConfectioneryView.csproj", "{90E59686-3070-4B0F-BCBF-AAE0FEFE35FA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryFileImplement", "ConfectioneryFileImplement\ConfectioneryFileImplement.csproj", "{BB6D6796-AD42-44BA-9BCC-27D8E1F6D068}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryFileImplement", "ConfectioneryFileImplement\ConfectioneryFileImplement.csproj", "{BB6D6796-AD42-44BA-9BCC-27D8E1F6D068}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryDatabaseImplement", "ConfectioneryDatabaseImplement\ConfectioneryDatabaseImplement.csproj", "{F637E749-7A91-4608-908F-4DA0434AB30B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConfectioneryDatabaseImplement", "ConfectioneryDatabaseImplement\ConfectioneryDatabaseImplement.csproj", "{F637E749-7A91-4608-908F-4DA0434AB30B}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConfectioneryRestApi", "ConfectioneryRestApi\ConfectioneryRestApi.csproj", "{1BD83A84-53DA-422D-8878-96100A1FD06F}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -51,6 +53,10 @@ Global {F637E749-7A91-4608-908F-4DA0434AB30B}.Debug|Any CPU.Build.0 = Debug|Any CPU {F637E749-7A91-4608-908F-4DA0434AB30B}.Release|Any CPU.ActiveCfg = Release|Any CPU {F637E749-7A91-4608-908F-4DA0434AB30B}.Release|Any CPU.Build.0 = Release|Any CPU + {1BD83A84-53DA-422D-8878-96100A1FD06F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1BD83A84-53DA-422D-8878-96100A1FD06F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1BD83A84-53DA-422D-8878-96100A1FD06F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1BD83A84-53DA-422D-8878-96100A1FD06F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Confectionery/ConfectioneryBusinessLogic/ClientLogic.cs b/Confectionery/ConfectioneryBusinessLogic/ClientLogic.cs new file mode 100644 index 0000000..0af56eb --- /dev/null +++ b/Confectionery/ConfectioneryBusinessLogic/ClientLogic.cs @@ -0,0 +1,123 @@ +using ConfectioneryContracts.BindingModels; +using ConfectioneryContracts.SearchModels; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryContracts.ViewModels; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ConfectioneryBusinessLogic +{ + public class ClientLogic + { + private readonly ILogger _logger; + private readonly IClientStorage _clientStorage; + + public ClientLogic(ILogger logger, IClientStorage clientStorage) + { + _logger = logger; + _clientStorage = clientStorage; + } + + public List? ReadList(ClientSearchModel? model) + { + _logger.LogInformation("ReadList. ClientId:{Id}", model?.Id); + var list = model == null ? _clientStorage.GetFullList() : _clientStorage.GetFilteredList(model); + if (list == null) + { + _logger.LogWarning("ReadList return null list"); + return null; + } + _logger.LogInformation("ReadList. Count:{Count}", list.Count); + return list; + } + + public ClientViewModel? ReadElement(ClientSearchModel model) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + _logger.LogInformation("ReadElement. ClientFio:{ClientFio}.Id:{ Id}", model.ClientFIO, model.Id); + var element = _clientStorage.GetElement(model); + if (element == null) + { + _logger.LogWarning("ReadElement element not found"); + return null; + } + _logger.LogInformation("ReadElement find. Id:{Id}", element.Id); + return element; + } + + public bool Create(ClientBindingModel model) + { + CheckModel(model); + if (_clientStorage.Insert(model) == null) + { + _logger.LogWarning("Insert operation failed"); + return false; + } + return true; + } + + public bool Update(ClientBindingModel model) + { + CheckModel(model); + if (_clientStorage.Update(model) == null) + { + _logger.LogWarning("Update operation failed"); + return false; + } + return true; + } + + public bool Delete(ClientBindingModel model) + { + CheckModel(model, false); + _logger.LogInformation("Delete. Id:{Id}", model.Id); + if (_clientStorage.Delete(model) == null) + { + _logger.LogWarning("Delete operation failed"); + return false; + } + return true; + } + + private void CheckModel(ClientBindingModel model, bool withParams = true) + { + if (model == null) + { + throw new ArgumentNullException(nameof(model)); + } + if (!withParams) + { + return; + } + if (string.IsNullOrEmpty(model.ClientFIO)) + { + throw new ArgumentNullException("Нет ФИО пользователя", nameof(model.ClientFIO)); + } + if (string.IsNullOrEmpty(model.Email)) + { + throw new ArgumentNullException("Нет почты пользователя", nameof(model.Email)); + } + if (string.IsNullOrEmpty(model.Password)) + { + throw new ArgumentNullException("Нет пароля пользователя", nameof(model.Password)); + } + _logger.LogInformation("Client. ClientFIO:{ClientFIO}.Email:{Email}.Password:{Password}.Id:{Id}", + model.ClientFIO, model.Email, model.Password, model.Id); + var element = _clientStorage.GetElement(new ClientSearchModel + { + ClientFIO = model.ClientFIO + }); + if (element != null && element.Id != model.Id) + { + throw new InvalidOperationException("Клиент с таким именем уже есть"); + } + } + } +} diff --git a/Confectionery/ConfectioneryDatabaseImplement/ClientStorage.cs b/Confectionery/ConfectioneryDatabaseImplement/ClientStorage.cs index 444eae4..6a4be8b 100644 --- a/Confectionery/ConfectioneryDatabaseImplement/ClientStorage.cs +++ b/Confectionery/ConfectioneryDatabaseImplement/ClientStorage.cs @@ -9,7 +9,7 @@ using ConfectioneryContracts.StoragesContracts; using ConfectioneryContracts.ViewModels; using ConfectioneryDatabaseImplement.Models; -namespace ConfectioneryDatabaseImplement +namespace ConfectioneryDatabaseImplement.Implements { public class ClientStorage : IClientStorage { diff --git a/Confectionery/ConfectioneryRestApi/ConfectioneryRestApi.csproj b/Confectionery/ConfectioneryRestApi/ConfectioneryRestApi.csproj new file mode 100644 index 0000000..c7429dd --- /dev/null +++ b/Confectionery/ConfectioneryRestApi/ConfectioneryRestApi.csproj @@ -0,0 +1,19 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + diff --git a/Confectionery/ConfectioneryRestApi/ConfectioneryRestApi.http b/Confectionery/ConfectioneryRestApi/ConfectioneryRestApi.http new file mode 100644 index 0000000..94883ad --- /dev/null +++ b/Confectionery/ConfectioneryRestApi/ConfectioneryRestApi.http @@ -0,0 +1,6 @@ +@ConfectioneryRestApi_HostAddress = http://localhost:5011 + +GET {{ConfectioneryRestApi_HostAddress}}/weatherforecast/ +Accept: application/json + +### diff --git a/Confectionery/ConfectioneryRestApi/Controllers/WeatherForecastController.cs b/Confectionery/ConfectioneryRestApi/Controllers/WeatherForecastController.cs new file mode 100644 index 0000000..c073e3d --- /dev/null +++ b/Confectionery/ConfectioneryRestApi/Controllers/WeatherForecastController.cs @@ -0,0 +1,33 @@ +using Microsoft.AspNetCore.Mvc; + +namespace ConfectioneryRestApi.Controllers +{ + [ApiController] + [Route("[controller]")] + public class WeatherForecastController : ControllerBase + { + private static readonly string[] Summaries = new[] + { + "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" + }; + + private readonly ILogger _logger; + + public WeatherForecastController(ILogger logger) + { + _logger = logger; + } + + [HttpGet(Name = "GetWeatherForecast")] + public IEnumerable Get() + { + return Enumerable.Range(1, 5).Select(index => new WeatherForecast + { + Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)), + TemperatureC = Random.Shared.Next(-20, 55), + Summary = Summaries[Random.Shared.Next(Summaries.Length)] + }) + .ToArray(); + } + } +} diff --git a/Confectionery/ConfectioneryRestApi/Program.cs b/Confectionery/ConfectioneryRestApi/Program.cs new file mode 100644 index 0000000..98b09e0 --- /dev/null +++ b/Confectionery/ConfectioneryRestApi/Program.cs @@ -0,0 +1,39 @@ +using ConfectioneryBusinessLogic; +using ConfectioneryContracts.BusinessLogicsContracts; +using ConfectioneryContracts.StoragesContracts; +using ConfectioneryDatabaseImplement.Implements; +using Microsoft.OpenApi.Models; +var builder = WebApplication.CreateBuilder(args); +builder.Logging.SetMinimumLevel(LogLevel.Trace); +builder.Logging.AddLog4Net("log4net.config"); +// Add services to the container. +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddTransient(); +builder.Services.AddControllers(); +// Learn more about configuring Swagger/OpenAPI at +https://aka.ms/aspnetcore/swashbuckle +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(c => +{ + c.SwaggerDoc("v1", new OpenApiInfo + { + Title = "ConfectioneryRestApi", + Version = "v1" + }); +}); +var app = builder.Build(); +// Configure the HTTP request pipeline. +if (app.Environment.IsDevelopment()) +{ + app.UseSwagger(); + app.UseSwaggerUI(c => c.SwaggerEndpoint("/swagger/v1/swagger.json", + "ConfectioneryRestApi v1")); +} +app.UseHttpsRedirection(); +app.UseAuthorization(); +app.MapControllers(); +app.Run(); \ No newline at end of file diff --git a/Confectionery/ConfectioneryRestApi/Properties/launchSettings.json b/Confectionery/ConfectioneryRestApi/Properties/launchSettings.json new file mode 100644 index 0000000..26efbe7 --- /dev/null +++ b/Confectionery/ConfectioneryRestApi/Properties/launchSettings.json @@ -0,0 +1,41 @@ +{ + "$schema": "http://json.schemastore.org/launchsettings.json", + "iisSettings": { + "windowsAuthentication": false, + "anonymousAuthentication": true, + "iisExpress": { + "applicationUrl": "http://localhost:32940", + "sslPort": 44390 + } + }, + "profiles": { + "http": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "http://localhost:5011", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "https": { + "commandName": "Project", + "dotnetRunMessages": true, + "launchBrowser": true, + "launchUrl": "swagger", + "applicationUrl": "https://localhost:7116;http://localhost:5011", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + }, + "IIS Express": { + "commandName": "IISExpress", + "launchBrowser": true, + "launchUrl": "swagger", + "environmentVariables": { + "ASPNETCORE_ENVIRONMENT": "Development" + } + } + } +} diff --git a/Confectionery/ConfectioneryRestApi/WeatherForecast.cs b/Confectionery/ConfectioneryRestApi/WeatherForecast.cs new file mode 100644 index 0000000..63fe779 --- /dev/null +++ b/Confectionery/ConfectioneryRestApi/WeatherForecast.cs @@ -0,0 +1,13 @@ +namespace ConfectioneryRestApi +{ + public class WeatherForecast + { + public DateOnly Date { get; set; } + + public int TemperatureC { get; set; } + + public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); + + public string? Summary { get; set; } + } +} diff --git a/Confectionery/ConfectioneryRestApi/appsettings.Development.json b/Confectionery/ConfectioneryRestApi/appsettings.Development.json new file mode 100644 index 0000000..0c208ae --- /dev/null +++ b/Confectionery/ConfectioneryRestApi/appsettings.Development.json @@ -0,0 +1,8 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + } +} diff --git a/Confectionery/ConfectioneryRestApi/appsettings.json b/Confectionery/ConfectioneryRestApi/appsettings.json new file mode 100644 index 0000000..10f68b8 --- /dev/null +++ b/Confectionery/ConfectioneryRestApi/appsettings.json @@ -0,0 +1,9 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*" +}