From 23cf04f4d0f42ff683840e039dbd73b20ebcc489 Mon Sep 17 00:00:00 2001 From: dmitry Date: Wed, 27 Jan 2021 15:12:09 +0500 Subject: [PATCH 01/22] =?UTF-8?q?=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20l2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UI/WebStore/Startup.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/UI/WebStore/Startup.cs b/UI/WebStore/Startup.cs index de4f804..f2b59ac 100644 --- a/UI/WebStore/Startup.cs +++ b/UI/WebStore/Startup.cs @@ -26,6 +26,7 @@ public class Startup { // This method gets called by the runtime. Use this method to add services to the container. // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 + private readonly IConfiguration _Configuration; public Startup(IConfiguration Configuration) => _Configuration = Configuration; From 1969eb1ba8911da41e90d34d5b703701a964ed4c Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 12:50:50 +0500 Subject: [PATCH 02/22] =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D0=BA=D0=BB=D1=8E?= =?UTF-8?q?=D1=87=D0=B5=D0=BD=D0=B8=D1=8F=20=D1=81=D0=B5=D1=80=D0=B2=D0=B8?= =?UTF-8?q?=D1=81=D0=BE=D0=B2=20=D0=B2=20=D0=BA=D0=BE=D0=BD=D1=82=D0=B5?= =?UTF-8?q?=D0=B9=D0=BD=D0=B5=D1=80=20=D1=81=D0=B5=D1=80=D0=B2=D0=B8=D1=81?= =?UTF-8?q?=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Services/WebStore.ServiceHosting/Startup.cs | 45 +++++++++++++- .../WebStore.ServiceHosting.csproj | 7 +++ .../WebStore.ServiceHosting/appsettings.json | 3 + UI/WebStore/Startup.cs | 60 +++++++++---------- 4 files changed, 82 insertions(+), 33 deletions(-) diff --git a/Services/WebStore.ServiceHosting/Startup.cs b/Services/WebStore.ServiceHosting/Startup.cs index f4cb774..8071915 100644 --- a/Services/WebStore.ServiceHosting/Startup.cs +++ b/Services/WebStore.ServiceHosting/Startup.cs @@ -1,6 +1,8 @@ using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.AspNetCore.Identity; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -10,6 +12,13 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using Webstore.DAL.Context; +using Webstore.Interfaces.Services; +using Webstore.Services.Data; +using Webstore.Services.Products; +using Webstore.Services.Products.InCookies; +using Webstore.Services.Products.InSql; +using WebStore.Domain.Entities.Identity; namespace WebStore.ServiceHosting { @@ -17,14 +26,43 @@ public class Startup { public Startup(IConfiguration configuration) { - Configuration = configuration; + _Configuration = configuration; } - public IConfiguration Configuration { get; } + private readonly IConfiguration _Configuration; // This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { + services.AddDbContext(opt => opt.UseSqlServer(_Configuration.GetConnectionString("Default"))); + services.AddTransient(); + + services.AddIdentity() + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + + services.AddSingleton(); + services.AddTransient(); + services.AddScoped(); + services.AddScoped(); + + services.Configure(opt => + { +#if DEBUG + opt.Password.RequiredLength = 3; + opt.Password.RequireDigit = false; + opt.Password.RequireLowercase = false; + opt.Password.RequireUppercase = false; + opt.Password.RequireNonAlphanumeric = false; + opt.Password.RequiredUniqueChars = 3; +#endif + opt.User.RequireUniqueEmail = false; + opt.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + + opt.Lockout.AllowedForNewUsers = true; + opt.Lockout.MaxFailedAccessAttempts = 10; + opt.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10); + }); services.AddControllers(); services.AddSwaggerGen(c => @@ -34,8 +72,9 @@ public void ConfigureServices(IServiceCollection services) } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, WebStoreDbInitializer db) { + db.Initialize(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); diff --git a/Services/WebStore.ServiceHosting/WebStore.ServiceHosting.csproj b/Services/WebStore.ServiceHosting/WebStore.ServiceHosting.csproj index 2884716..7169942 100644 --- a/Services/WebStore.ServiceHosting/WebStore.ServiceHosting.csproj +++ b/Services/WebStore.ServiceHosting/WebStore.ServiceHosting.csproj @@ -8,4 +8,11 @@ + + + + + + + diff --git a/Services/WebStore.ServiceHosting/appsettings.json b/Services/WebStore.ServiceHosting/appsettings.json index d9d9a9b..f455cbb 100644 --- a/Services/WebStore.ServiceHosting/appsettings.json +++ b/Services/WebStore.ServiceHosting/appsettings.json @@ -1,4 +1,7 @@ { + "ConnectionStrings": { + "Default": "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=WebStore-DB" + }, "Logging": { "LogLevel": { "Default": "Information", diff --git a/UI/WebStore/Startup.cs b/UI/WebStore/Startup.cs index f2b59ac..13b9aae 100644 --- a/UI/WebStore/Startup.cs +++ b/UI/WebStore/Startup.cs @@ -32,30 +32,30 @@ public class Startup public Startup(IConfiguration Configuration) => _Configuration = Configuration; public void ConfigureServices(IServiceCollection services) { - services.AddDbContext(opt => opt.UseSqlServer(_Configuration.GetConnectionString("Default"))); - services.AddTransient(); - - services.AddIdentity() - .AddEntityFrameworkStores() - .AddDefaultTokenProviders(); - - services.Configure(opt => - { -#if DEBUG - opt.Password.RequiredLength = 3; - opt.Password.RequireDigit = false; - opt.Password.RequireLowercase = false; - opt.Password.RequireUppercase = false; - opt.Password.RequireNonAlphanumeric = false; - opt.Password.RequiredUniqueChars = 3; -#endif - opt.User.RequireUniqueEmail = false; - opt.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; - - opt.Lockout.AllowedForNewUsers = true; - opt.Lockout.MaxFailedAccessAttempts = 10; - opt.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10); - }); +// services.AddDbContext(opt => opt.UseSqlServer(_Configuration.GetConnectionString("Default"))); +// services.AddTransient(); + +// services.AddIdentity() +// .AddEntityFrameworkStores() +// .AddDefaultTokenProviders(); + +// services.Configure(opt => +// { +//#if DEBUG +// opt.Password.RequiredLength = 3; +// opt.Password.RequireDigit = false; +// opt.Password.RequireLowercase = false; +// opt.Password.RequireUppercase = false; +// opt.Password.RequireNonAlphanumeric = false; +// opt.Password.RequiredUniqueChars = 3; +//#endif +// opt.User.RequireUniqueEmail = false; +// opt.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + +// opt.Lockout.AllowedForNewUsers = true; +// opt.Lockout.MaxFailedAccessAttempts = 10; +// opt.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10); +// }); services.ConfigureApplicationCookie(opt => { @@ -71,21 +71,21 @@ public void ConfigureServices(IServiceCollection services) }); services.AddControllersWithViews().AddRazorRuntimeCompilation(); - services.AddSingleton(); + //services.AddSingleton(); //services.AddTransient(); - services.AddTransient(); + //services.AddTransient(); //InMemoryBlogsData: IBlogsData services.AddSingleton(); - services.AddScoped(); - services.AddScoped(); + //services.AddScoped(); + //services.AddScoped(); services.AddScoped(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env, WebStoreDbInitializer db) + public void Configure(IApplicationBuilder app, IWebHostEnvironment env)/*, WebStoreDbInitializer db)*/ { - db.Initialize(); + //db.Initialize(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); From 8fa07164067a3ed7a53af223ab4b47f01cd5f5da Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 13:02:49 +0500 Subject: [PATCH 03/22] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE=D0=BB=D0=BB=D0=B5?= =?UTF-8?q?=D1=80=20api=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=BE=D1=82=D1=80?= =?UTF-8?q?=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/EmployeesApiController.cs | 53 ++++++++++++++++ UI/WebStore/Startup.cs | 61 +++++++++---------- 2 files changed, 83 insertions(+), 31 deletions(-) create mode 100644 Services/WebStore.ServiceHosting/Controllers/EmployeesApiController.cs diff --git a/Services/WebStore.ServiceHosting/Controllers/EmployeesApiController.cs b/Services/WebStore.ServiceHosting/Controllers/EmployeesApiController.cs new file mode 100644 index 0000000..44ccddc --- /dev/null +++ b/Services/WebStore.ServiceHosting/Controllers/EmployeesApiController.cs @@ -0,0 +1,53 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Webstore.Interfaces.Services; +using WebStore.Domain.Models; + +namespace WebStore.ServiceHosting.Controllers +{ + [Route("api/[controller]")] + [ApiController] + public class EmployeesApiController : ControllerBase, IEmployeesData + { + private readonly IEmployeesData _db; + + public EmployeesApiController(IEmployeesData db) + { + _db = db; + } + + [HttpPost] + public int Add(Employee employee) + { + return _db.Add(employee); + } + + [HttpDelete("{id}")] + public bool Delete(int id) + { + return _db.Delete(id); + } + + [HttpGet] + public IEnumerable Get() + { + return _db.Get(); + } + + [HttpGet("{id}")] + public Employee Get(int id) + { + return _db.Get(id); + } + + [HttpPut] + public void Update(Employee employee) + { + _db.Update(employee); + } + } +} diff --git a/UI/WebStore/Startup.cs b/UI/WebStore/Startup.cs index 13b9aae..e334c0f 100644 --- a/UI/WebStore/Startup.cs +++ b/UI/WebStore/Startup.cs @@ -32,30 +32,30 @@ public class Startup public Startup(IConfiguration Configuration) => _Configuration = Configuration; public void ConfigureServices(IServiceCollection services) { -// services.AddDbContext(opt => opt.UseSqlServer(_Configuration.GetConnectionString("Default"))); -// services.AddTransient(); - -// services.AddIdentity() -// .AddEntityFrameworkStores() -// .AddDefaultTokenProviders(); - -// services.Configure(opt => -// { -//#if DEBUG -// opt.Password.RequiredLength = 3; -// opt.Password.RequireDigit = false; -// opt.Password.RequireLowercase = false; -// opt.Password.RequireUppercase = false; -// opt.Password.RequireNonAlphanumeric = false; -// opt.Password.RequiredUniqueChars = 3; -//#endif -// opt.User.RequireUniqueEmail = false; -// opt.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; - -// opt.Lockout.AllowedForNewUsers = true; -// opt.Lockout.MaxFailedAccessAttempts = 10; -// opt.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10); -// }); + services.AddDbContext(opt => opt.UseSqlServer(_Configuration.GetConnectionString("Default"))); + services.AddTransient(); + + services.AddIdentity() + .AddEntityFrameworkStores() + .AddDefaultTokenProviders(); + + services.Configure(opt => + { +#if DEBUG + opt.Password.RequiredLength = 3; + opt.Password.RequireDigit = false; + opt.Password.RequireLowercase = false; + opt.Password.RequireUppercase = false; + opt.Password.RequireNonAlphanumeric = false; + opt.Password.RequiredUniqueChars = 3; +#endif + opt.User.RequireUniqueEmail = false; + opt.User.AllowedUserNameCharacters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890"; + + opt.Lockout.AllowedForNewUsers = true; + opt.Lockout.MaxFailedAccessAttempts = 10; + opt.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(10); + }); services.ConfigureApplicationCookie(opt => { @@ -71,21 +71,20 @@ public void ConfigureServices(IServiceCollection services) }); services.AddControllersWithViews().AddRazorRuntimeCompilation(); - //services.AddSingleton(); + services.AddSingleton(); //services.AddTransient(); - //services.AddTransient(); - //InMemoryBlogsData: IBlogsData + services.AddTransient(); services.AddSingleton(); - //services.AddScoped(); - //services.AddScoped(); + services.AddScoped(); + services.AddScoped(); services.AddScoped(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env)/*, WebStoreDbInitializer db)*/ + public void Configure(IApplicationBuilder app, IWebHostEnvironment env, WebStoreDbInitializer db) { - //db.Initialize(); + db.Initialize(); if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); From 03f97c9fcf2f7ed85005c4224caa5fea751931c9 Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 13:14:31 +0500 Subject: [PATCH 04/22] =?UTF-8?q?api=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80?= =?UTF-8?q?=D0=BE=D0=BB=D0=BB=D0=B5=D1=80=20=D1=81=D0=BE=D1=82=D1=80=D1=83?= =?UTF-8?q?=D0=B4=D0=BD=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/EmployeesApiController.cs | 31 +++++++++++++++++-- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/Services/WebStore.ServiceHosting/Controllers/EmployeesApiController.cs b/Services/WebStore.ServiceHosting/Controllers/EmployeesApiController.cs index 44ccddc..7f204cb 100644 --- a/Services/WebStore.ServiceHosting/Controllers/EmployeesApiController.cs +++ b/Services/WebStore.ServiceHosting/Controllers/EmployeesApiController.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; using System.Linq; @@ -14,22 +15,46 @@ namespace WebStore.ServiceHosting.Controllers public class EmployeesApiController : ControllerBase, IEmployeesData { private readonly IEmployeesData _db; + private readonly ILogger _Logger; - public EmployeesApiController(IEmployeesData db) + public EmployeesApiController(IEmployeesData db, ILogger Logger) { _db = db; + _Logger = Logger; } [HttpPost] public int Add(Employee employee) { - return _db.Add(employee); + if (!ModelState.IsValid) + { + _Logger.LogWarning("Ошибка модели данных при добавлении нового сотрудника {0} {1}", + employee.LastName, employee.FirstName); + return 0; + } + _Logger.LogInformation("Добавление сотрудника {0} {1}", + employee.LastName, employee.FirstName); + var id = _db.Add(employee); + if (id > 0) + _Logger.LogInformation("Cотрудник [id:{0}] {1} {2} добавлен успешно", + employee.Id, employee.LastName, employee.FirstName); + else + _Logger.LogWarning("Ошибка при добавлении сотрудника {0} {1}", + employee.LastName, employee.FirstName); + return id; } [HttpDelete("{id}")] public bool Delete(int id) { - return _db.Delete(id); + + var result = _db.Delete(id); + if (result) + _Logger.LogInformation("Сотрудник с id:{0} успешно удалён", id); + else + _Logger.LogWarning("ошибка при попытке удаления сотрдуника с id:{0}", id); + + return result; } [HttpGet] From 01c2d66043145e2d8602628a49a18078d683f322 Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 13:23:07 +0500 Subject: [PATCH 05/22] =?UTF-8?q?=D0=97=D0=B0=D0=B3=D0=BE=D1=82=D0=BE?= =?UTF-8?q?=D0=B2=D0=BA=D0=B0=20=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=D0=B0?= =?UTF-8?q?=20Emploees?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Employees/EmployeesClient.cs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 Services/WebStore.Client/Employees/EmployeesClient.cs diff --git a/Services/WebStore.Client/Employees/EmployeesClient.cs b/Services/WebStore.Client/Employees/EmployeesClient.cs new file mode 100644 index 0000000..3124d0a --- /dev/null +++ b/Services/WebStore.Client/Employees/EmployeesClient.cs @@ -0,0 +1,46 @@ +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Text; +using Webstore.Interfaces.Services; +using WebStore.Client.Base; +using WebStore.Domain.Models; + +namespace WebStore.Client.Employees +{ + public class EmployeesClient: BaseClient, IEmployeesData + { + private readonly ILogger logger; + + public EmployeesClient(IConfiguration Configuration, ILogger Logger): base(Configuration, "api/employees") + { + logger = Logger; + } + + public int Add(Employee employee) + { + throw new NotImplementedException(); + } + + public bool Delete(int id) + { + throw new NotImplementedException(); + } + + public IEnumerable Get() + { + throw new NotImplementedException(); + } + + public Employee Get(int id) + { + throw new NotImplementedException(); + } + + public void Update(Employee employee) + { + throw new NotImplementedException(); + } + } +} From cd4bc9d7cdb21d36f10102c77af47214aa2a9bbd Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 13:32:35 +0500 Subject: [PATCH 06/22] =?UTF-8?q?=D0=A0=D0=B0=D1=81=D1=88=D0=B8=D1=80?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=B1=D0=B0=D0=B7=D0=BE=D0=B2=D0=BE?= =?UTF-8?q?=D0=B3=D0=BE=20=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Services/WebStore.Client/Base/BaseClient.cs | 32 +++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/Services/WebStore.Client/Base/BaseClient.cs b/Services/WebStore.Client/Base/BaseClient.cs index 00a968e..b587d52 100644 --- a/Services/WebStore.Client/Base/BaseClient.cs +++ b/Services/WebStore.Client/Base/BaseClient.cs @@ -1,6 +1,7 @@ using System; using System.Net.Http; using System.Net.Http.Headers; +using System.Threading.Tasks; using Microsoft.Extensions.Configuration; namespace WebStore.Client.Base @@ -22,5 +23,36 @@ protected BaseClient(IConfiguration Configuration, string ServiceAddress) } }; } + + protected T Get(string url) => GetAsync(url).Result; + protected async Task GetAsync(string url) + { + var response = await Http.GetAsync(url); + return await response.EnsureSuccessStatusCode().Content.ReadAsAsync(); + } + + protected HttpResponseMessage Post(string url, T item) => PostAsync(url, item).Result; + + protected async Task PostAsync(string url, T item) + { + var response = await Http.PostAsJsonAsync(url, item); + return response.EnsureSuccessStatusCode(); + } + + protected HttpResponseMessage Put(string url, T item) => PutAsync(url, item).Result; + + protected async Task PutAsync(string url, T item) + { + var response = await Http.PutAsJsonAsync(url, item); + return response.EnsureSuccessStatusCode(); + } + + protected HttpResponseMessage Delete(string url) => DeleteAsync(url).Result; + + protected async Task DeleteAsync(string url) + { + var response = await Http.DeleteAsync(url); + return response; + } } } From 938b543c37133e926e13291448d9635e6e579c3e Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 13:39:20 +0500 Subject: [PATCH 07/22] =?UTF-8?q?=D0=9A=D0=BB=D0=B8=D0=B5=D0=BD=D1=82=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD?= =?UTF-8?q?=D0=B8=D0=BA=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Employees/EmployeesClient.cs | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/Services/WebStore.Client/Employees/EmployeesClient.cs b/Services/WebStore.Client/Employees/EmployeesClient.cs index 3124d0a..235e727 100644 --- a/Services/WebStore.Client/Employees/EmployeesClient.cs +++ b/Services/WebStore.Client/Employees/EmployeesClient.cs @@ -2,6 +2,7 @@ using Microsoft.Extensions.Logging; using System; using System.Collections.Generic; +using System.Net.Http; using System.Text; using Webstore.Interfaces.Services; using WebStore.Client.Base; @@ -11,36 +12,25 @@ namespace WebStore.Client.Employees { public class EmployeesClient: BaseClient, IEmployeesData { - private readonly ILogger logger; + private readonly ILogger _Logger; public EmployeesClient(IConfiguration Configuration, ILogger Logger): base(Configuration, "api/employees") { - logger = Logger; + _Logger = Logger; } - public int Add(Employee employee) - { - throw new NotImplementedException(); - } + public int Add(Employee employee)=>Post(Address,employee).Content.ReadAsAsync().Result; - public bool Delete(int id) - { - throw new NotImplementedException(); - } + public bool Delete(int id) => Delete($"{Address}/{id}").IsSuccessStatusCode; - public IEnumerable Get() - { - throw new NotImplementedException(); - } + public IEnumerable Get() => Get>(Address); - public Employee Get(int id) - { - throw new NotImplementedException(); - } + public Employee Get(int id) => Get($"{Address}/{id}"); public void Update(Employee employee) { - throw new NotImplementedException(); + _Logger.LogInformation("Редактирование сотрудника с id:{ 0}", employee.Id); + Put(Address, employee); } } } From 6ba7e97ae524a60b6931f82ea80050863226ddd5 Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 16:47:30 +0500 Subject: [PATCH 08/22] =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D0=BA=D0=BB=D1=8E.?= =?UTF-8?q?=D1=87=D0=B8=D0=BB=D0=B8=20=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82?= =?UTF-8?q?=20=D1=81=D0=BE=D1=82=D1=80=D1=83=D0=B4=D0=BD=D0=B8=D0=BA=D0=BE?= =?UTF-8?q?=D0=B2=20=D0=BA=20=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D0=BE?= =?UTF-8?q?=D0=BC=D1=83=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/EmployeesApiController.cs | 2 +- UI/WebStore/Startup.cs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Services/WebStore.ServiceHosting/Controllers/EmployeesApiController.cs b/Services/WebStore.ServiceHosting/Controllers/EmployeesApiController.cs index 7f204cb..9e91be0 100644 --- a/Services/WebStore.ServiceHosting/Controllers/EmployeesApiController.cs +++ b/Services/WebStore.ServiceHosting/Controllers/EmployeesApiController.cs @@ -10,7 +10,7 @@ namespace WebStore.ServiceHosting.Controllers { - [Route("api/[controller]")] + [Route("api/employees")] [ApiController] public class EmployeesApiController : ControllerBase, IEmployeesData { diff --git a/UI/WebStore/Startup.cs b/UI/WebStore/Startup.cs index e334c0f..dd8472a 100644 --- a/UI/WebStore/Startup.cs +++ b/UI/WebStore/Startup.cs @@ -19,6 +19,7 @@ using Webstore.Services.Products.InSql; using WebStore.Client.Values; using WebStore.Interfaces.TestAPI; +using WebStore.Client.Employees; namespace WebStore { @@ -71,7 +72,7 @@ public void ConfigureServices(IServiceCollection services) }); services.AddControllersWithViews().AddRazorRuntimeCompilation(); - services.AddSingleton(); + services.AddSingleton(); //services.AddTransient(); services.AddTransient(); services.AddSingleton(); From 11ef00325dc8d57b63f439c7aff5dfad0bc08b6b Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 17:05:34 +0500 Subject: [PATCH 09/22] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=B2=D0=BE=D0=B7=D0=BC=D0=BE=D0=B6=D0=BD=D0=BE=D1=81?= =?UTF-8?q?=D1=82=D1=8C=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F=20=D0=B1=D1=80=D0=B5=D0=BD=D0=B4=D0=B0=20=D0=B8=20=D0=BA?= =?UTF-8?q?=D0=B0=D1=82=D0=B5=D0=B3=D0=BE=D1=80=D0=BD=D0=B8=D0=B8=20=D0=BF?= =?UTF-8?q?=D0=BE=20id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Services/Webstore.Interfaces/Services/IProductData.cs | 4 ++++ .../Webstore.Services/Products/InMemoryProductsData.cs | 10 ++++++++++ .../Products/InSql/InSqIProductData.cs | 10 ++++++++++ 3 files changed, 24 insertions(+) diff --git a/Services/Webstore.Interfaces/Services/IProductData.cs b/Services/Webstore.Interfaces/Services/IProductData.cs index 2c753ed..b6e46b5 100644 --- a/Services/Webstore.Interfaces/Services/IProductData.cs +++ b/Services/Webstore.Interfaces/Services/IProductData.cs @@ -8,7 +8,11 @@ public interface IProductData { IEnumerable GetСategories(); + Category GetСategoriesById(int id); + IEnumerable GetBrands(); + + Brand GetBrandsById(int id); IEnumerable GetProducts(ProductFilter Filter = null); diff --git a/Services/Webstore.Services/Products/InMemoryProductsData.cs b/Services/Webstore.Services/Products/InMemoryProductsData.cs index 885aca1..e179639 100644 --- a/Services/Webstore.Services/Products/InMemoryProductsData.cs +++ b/Services/Webstore.Services/Products/InMemoryProductsData.cs @@ -31,5 +31,15 @@ public Product GetProductById(int id) { throw new NotImplementedException(); } + + public Category GetСategoriesById(int id) + { + throw new NotImplementedException(); + } + + public Brand GetBrandsById(int id) + { + throw new NotImplementedException(); + } } } diff --git a/Services/Webstore.Services/Products/InSql/InSqIProductData.cs b/Services/Webstore.Services/Products/InSql/InSqIProductData.cs index 250a022..729a146 100644 --- a/Services/Webstore.Services/Products/InSql/InSqIProductData.cs +++ b/Services/Webstore.Services/Products/InSql/InSqIProductData.cs @@ -21,6 +21,11 @@ public InSqIProductData(WebStoreDB db) public IEnumerable GetBrands() => _db.Brands.Include(brand => brand.Products); + public Brand GetBrandsById(int id) + { + throw new NotImplementedException(); + } + public Product GetProductById(int id) { return _db.Products.Include(p => p.Brand).Include(p => p.Category).FirstOrDefault(p => p.Id == id); @@ -47,5 +52,10 @@ public IEnumerable GetProducts(ProductFilter Filter = null) } public IEnumerable GetСategories() => _db.Categories.Include(category => category.Products); + + public Category GetСategoriesById(int id) + { + throw new NotImplementedException(); + } } } From 74aedb9491a1762286b6bb8f64fa79e0ecc24496 Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 17:06:07 +0500 Subject: [PATCH 10/22] =?UTF-8?q?=D1=80=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7?= =?UTF-8?q?=D0=BE=D0=B2=D0=B0=D0=BB=20=D0=BC=D0=B5=D1=82=D0=BE=D0=B4=D1=8B?= =?UTF-8?q?=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9=D1=81=D0=B0?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D0=BF=D0=BE=D0=BB=D1=83=D1=87=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F=20=D0=BA=D0=B0=D1=82=D0=B5=D0=B3=D0=BE=D0=B8?= =?UTF-8?q?=D1=80=D0=B8=D0=B8=20=D0=B8=20=D0=B1=D1=80=D0=B5=D0=BD=D0=B4?= =?UTF-8?q?=D0=B0=20=D0=BF=D0=BE=20id?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Services/Webstore.Services/Products/InSql/InSqIProductData.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Services/Webstore.Services/Products/InSql/InSqIProductData.cs b/Services/Webstore.Services/Products/InSql/InSqIProductData.cs index 729a146..c8f81c7 100644 --- a/Services/Webstore.Services/Products/InSql/InSqIProductData.cs +++ b/Services/Webstore.Services/Products/InSql/InSqIProductData.cs @@ -23,7 +23,7 @@ public InSqIProductData(WebStoreDB db) public Brand GetBrandsById(int id) { - throw new NotImplementedException(); + return _db.Brands.Include(brand => brand.Products).FirstOrDefault(brand => brand.Id == id); } public Product GetProductById(int id) @@ -55,7 +55,7 @@ public IEnumerable GetProducts(ProductFilter Filter = null) public Category GetСategoriesById(int id) { - throw new NotImplementedException(); + return _db.Categories.Include(category => category.Products).FirstOrDefault(category => category.Id == id); } } } From 3698f456addac99c8c13f13f7e0d7425e3529d70 Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 17:06:20 +0500 Subject: [PATCH 11/22] =?UTF-8?q?=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=BE?= =?UTF-8?q?=D0=BB=D0=BB=D0=B5=D1=80=20=D0=B4=D0=BB=D1=8F=20=D1=82=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ProductsApiController.cs | 64 +++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs diff --git a/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs b/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs new file mode 100644 index 0000000..d18056b --- /dev/null +++ b/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs @@ -0,0 +1,64 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Webstore.Interfaces.Services; +using WebStore.Domain; +using WebStore.Domain.Entities; + +namespace WebStore.ServiceHosting.Controllers +{ + [Route("api/products")] + [ApiController] + public class ProductsApiController : ControllerBase, IProductData + { + private readonly IProductData _db; + private readonly ILogger _Logger; + + public ProductsApiController(IProductData db, ILogger Logger) + { + _db = db; + _Logger = Logger; + } + + [HttpGet("brands")] + public IEnumerable GetBrands() + { + return _db.GetBrands(); + } + + [HttpGet("brands/{id}")] + public Brand GetBrandsById(int id) + { + throw new NotImplementedException(); + } + + [HttpGet("products/{id}")] + public Product GetProductById(int id) + { + return _db.GetProductById(id); + } + + + [HttpGet("products")] + public IEnumerable GetProducts(ProductFilter Filter = null) + { + return _db.GetProducts(Filter); + } + + [HttpGet("categories")] + public IEnumerable GetСategories() + { + return _db.GetСategories(); + } + + [HttpGet("categories/{id}")] + public Category GetСategoriesById(int id) + { + throw new NotImplementedException(); + } + } +} From 4e47daddde8e084f33c6621ad760e4cc2f6083e5 Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 17:07:56 +0500 Subject: [PATCH 12/22] =?UTF-8?q?=D1=80=D0=B5=D1=84=D0=B0=D0=BA=D1=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ProductsApiController.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs b/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs index d18056b..1fe2977 100644 --- a/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs +++ b/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs @@ -36,15 +36,15 @@ public Brand GetBrandsById(int id) throw new NotImplementedException(); } - [HttpGet("products/{id}")] + [HttpGet("{id}")] public Product GetProductById(int id) { return _db.GetProductById(id); } - [HttpGet("products")] - public IEnumerable GetProducts(ProductFilter Filter = null) + [HttpPost] + public IEnumerable GetProducts([FromBody]ProductFilter Filter = null) { return _db.GetProducts(Filter); } From b0f8dd98979ad484c3400fb09f78cd693a97f0c7 Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 17:20:45 +0500 Subject: [PATCH 13/22] =?UTF-8?q?=D0=9E=D0=BF=D0=B8=D1=81=D0=B0=D0=BB=20DT?= =?UTF-8?q?O?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WebStore.Domain/DTO/Products/BrandDTO.cs | 16 ++++++++++++++ .../DTO/Products/CategoryDTO.cs | 19 +++++++++++++++++ .../DTO/Products/ProductDTO.cs | 21 +++++++++++++++++++ Common/WebStore.Domain/WebStore.Domain.csproj | 4 ++-- 4 files changed, 58 insertions(+), 2 deletions(-) create mode 100644 Common/WebStore.Domain/DTO/Products/BrandDTO.cs create mode 100644 Common/WebStore.Domain/DTO/Products/CategoryDTO.cs create mode 100644 Common/WebStore.Domain/DTO/Products/ProductDTO.cs diff --git a/Common/WebStore.Domain/DTO/Products/BrandDTO.cs b/Common/WebStore.Domain/DTO/Products/BrandDTO.cs new file mode 100644 index 0000000..2fb9862 --- /dev/null +++ b/Common/WebStore.Domain/DTO/Products/BrandDTO.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WebStore.Domain.Entities.Base; + +namespace WebStore.Domain.DTO.Products +{ + class BrandDTO: NamedEntity + { + public int Order { get; set; } + + public int ProductsCount { get; set; } + } +} diff --git a/Common/WebStore.Domain/DTO/Products/CategoryDTO.cs b/Common/WebStore.Domain/DTO/Products/CategoryDTO.cs new file mode 100644 index 0000000..798c6f8 --- /dev/null +++ b/Common/WebStore.Domain/DTO/Products/CategoryDTO.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WebStore.Domain.Entities.Base; + +namespace WebStore.Domain.DTO.Products +{ + class CategoryDTO: NamedEntity + { + + public int Order { get; set; } + + public int? ParentId { get; set; } + + public int ProductsCount { get; set; } + } +} diff --git a/Common/WebStore.Domain/DTO/Products/ProductDTO.cs b/Common/WebStore.Domain/DTO/Products/ProductDTO.cs new file mode 100644 index 0000000..76f3a6f --- /dev/null +++ b/Common/WebStore.Domain/DTO/Products/ProductDTO.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WebStore.Domain.Entities.Base; + +namespace WebStore.Domain.DTO.Products +{ + class ProductDTO: NamedEntity + { + public int Order { get; set; } + public decimal Price { get; set; } + public string ImageUrl { get; set; } + public BrandDTO Brand { get; set; } + public CategoryDTO Category { get; set; } + public string Description { get; set; } + public int Discount { get; set; } + + } +} diff --git a/Common/WebStore.Domain/WebStore.Domain.csproj b/Common/WebStore.Domain/WebStore.Domain.csproj index e9a2516..0632141 100644 --- a/Common/WebStore.Domain/WebStore.Domain.csproj +++ b/Common/WebStore.Domain/WebStore.Domain.csproj @@ -1,7 +1,7 @@ - + - netstandard2.0 + net5.0 From fabbb8f435327dff759b71c81c05a2d1057e0bb8 Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 18:01:02 +0500 Subject: [PATCH 14/22] net5 --- Services/WebStore.Client/WebStore.Client.csproj | 2 +- Services/Webstore.Interfaces/Webstore.Interfaces.csproj | 2 +- Services/Webstore.Services/Webstore.Services.csproj | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Services/WebStore.Client/WebStore.Client.csproj b/Services/WebStore.Client/WebStore.Client.csproj index 5af1b39..d23926e 100644 --- a/Services/WebStore.Client/WebStore.Client.csproj +++ b/Services/WebStore.Client/WebStore.Client.csproj @@ -1,7 +1,7 @@ - netstandard2.1 + net5.0 diff --git a/Services/Webstore.Interfaces/Webstore.Interfaces.csproj b/Services/Webstore.Interfaces/Webstore.Interfaces.csproj index aa3cb70..2f2fc48 100644 --- a/Services/Webstore.Interfaces/Webstore.Interfaces.csproj +++ b/Services/Webstore.Interfaces/Webstore.Interfaces.csproj @@ -1,7 +1,7 @@ - netstandard2.1 + net5.0 diff --git a/Services/Webstore.Services/Webstore.Services.csproj b/Services/Webstore.Services/Webstore.Services.csproj index 794bced..459e7cd 100644 --- a/Services/Webstore.Services/Webstore.Services.csproj +++ b/Services/Webstore.Services/Webstore.Services.csproj @@ -1,7 +1,7 @@  - netstandard2.1 + net5.0 From 47b2861d53f477aee012a91c77a4b411eee92d72 Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 18:01:12 +0500 Subject: [PATCH 15/22] =?UTF-8?q?=D0=BE=D0=BF=D0=B8=D1=81=D0=B0=D0=BB=20DT?= =?UTF-8?q?O?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Common/WebStore.Domain/DTO/Products/BrandDTO.cs | 2 +- Common/WebStore.Domain/DTO/Products/CategoryDTO.cs | 2 +- Common/WebStore.Domain/DTO/Products/ProductDTO.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Common/WebStore.Domain/DTO/Products/BrandDTO.cs b/Common/WebStore.Domain/DTO/Products/BrandDTO.cs index 2fb9862..1fd121a 100644 --- a/Common/WebStore.Domain/DTO/Products/BrandDTO.cs +++ b/Common/WebStore.Domain/DTO/Products/BrandDTO.cs @@ -7,7 +7,7 @@ namespace WebStore.Domain.DTO.Products { - class BrandDTO: NamedEntity + public class BrandDTO: NamedEntity { public int Order { get; set; } diff --git a/Common/WebStore.Domain/DTO/Products/CategoryDTO.cs b/Common/WebStore.Domain/DTO/Products/CategoryDTO.cs index 798c6f8..996e962 100644 --- a/Common/WebStore.Domain/DTO/Products/CategoryDTO.cs +++ b/Common/WebStore.Domain/DTO/Products/CategoryDTO.cs @@ -7,7 +7,7 @@ namespace WebStore.Domain.DTO.Products { - class CategoryDTO: NamedEntity + public class CategoryDTO: NamedEntity { public int Order { get; set; } diff --git a/Common/WebStore.Domain/DTO/Products/ProductDTO.cs b/Common/WebStore.Domain/DTO/Products/ProductDTO.cs index 76f3a6f..2255f9d 100644 --- a/Common/WebStore.Domain/DTO/Products/ProductDTO.cs +++ b/Common/WebStore.Domain/DTO/Products/ProductDTO.cs @@ -7,7 +7,7 @@ namespace WebStore.Domain.DTO.Products { - class ProductDTO: NamedEntity + public class ProductDTO: NamedEntity { public int Order { get; set; } public decimal Price { get; set; } From 56f0c4a3948db4cfca62638d303fc150e5698281 Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 18:02:24 +0500 Subject: [PATCH 16/22] =?UTF-8?q?=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84?= =?UTF-8?q?=D0=B5=D0=B9=D1=81=20DTO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/ProductsApiController.cs | 15 +++++++------ .../Services/IProductDataDTO.cs | 22 +++++++++++++++++++ 2 files changed, 30 insertions(+), 7 deletions(-) create mode 100644 Services/Webstore.Interfaces/Services/IProductDataDTO.cs diff --git a/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs b/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs index 1fe2977..a2cda0d 100644 --- a/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs +++ b/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs @@ -7,13 +7,14 @@ using System.Threading.Tasks; using Webstore.Interfaces.Services; using WebStore.Domain; +using WebStore.Domain.DTO.Products; using WebStore.Domain.Entities; namespace WebStore.ServiceHosting.Controllers { [Route("api/products")] [ApiController] - public class ProductsApiController : ControllerBase, IProductData + public class ProductsApiController : ControllerBase, IProductDataDTO { private readonly IProductData _db; private readonly ILogger _Logger; @@ -25,38 +26,38 @@ public ProductsApiController(IProductData db, ILogger Log } [HttpGet("brands")] - public IEnumerable GetBrands() + public IEnumerable GetBrands() { return _db.GetBrands(); } [HttpGet("brands/{id}")] - public Brand GetBrandsById(int id) + public BrandDTO GetBrandsById(int id) { throw new NotImplementedException(); } [HttpGet("{id}")] - public Product GetProductById(int id) + public ProductDTO GetProductById(int id) { return _db.GetProductById(id); } [HttpPost] - public IEnumerable GetProducts([FromBody]ProductFilter Filter = null) + public IEnumerable GetProducts([FromBody]ProductFilter Filter = null) { return _db.GetProducts(Filter); } [HttpGet("categories")] - public IEnumerable GetСategories() + public IEnumerable GetСategories() { return _db.GetСategories(); } [HttpGet("categories/{id}")] - public Category GetСategoriesById(int id) + public CategoryDTO GetСategoriesById(int id) { throw new NotImplementedException(); } diff --git a/Services/Webstore.Interfaces/Services/IProductDataDTO.cs b/Services/Webstore.Interfaces/Services/IProductDataDTO.cs new file mode 100644 index 0000000..e1efe0a --- /dev/null +++ b/Services/Webstore.Interfaces/Services/IProductDataDTO.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using WebStore.Domain; +using WebStore.Domain.DTO.Products; +using WebStore.Domain.Entities; + +namespace Webstore.Interfaces.Services +{ + public interface IProductDataDTO + { + IEnumerable GetСategories(); + + CategoryDTO GetСategoriesById(int id); + + IEnumerable GetBrands(); + + BrandDTO GetBrandsById(int id); + + IEnumerable GetProducts(ProductFilter Filter = null); + + ProductDTO GetProductById(int id); + } +} From 9e8ac34a6e8e255f796a9dc04aa1abcc617d74e7 Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 20:39:12 +0500 Subject: [PATCH 17/22] mapping --- Services/Webstore.DAL/Webstore.DAL.csproj | 2 +- .../Webstore.Services/Mapping/BrandMapper.cs | 33 +++++++++++++++++ .../Mapping/CategoryMapper.cs | 34 +++++++++++++++++ .../Mapping/ProductMapper.cs | 37 ++++++++++++++++++- 4 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 Services/Webstore.Services/Mapping/BrandMapper.cs create mode 100644 Services/Webstore.Services/Mapping/CategoryMapper.cs diff --git a/Services/Webstore.DAL/Webstore.DAL.csproj b/Services/Webstore.DAL/Webstore.DAL.csproj index be79c82..d57450a 100644 --- a/Services/Webstore.DAL/Webstore.DAL.csproj +++ b/Services/Webstore.DAL/Webstore.DAL.csproj @@ -1,7 +1,7 @@ - netstandard2.1 + net5.0 diff --git a/Services/Webstore.Services/Mapping/BrandMapper.cs b/Services/Webstore.Services/Mapping/BrandMapper.cs new file mode 100644 index 0000000..298a701 --- /dev/null +++ b/Services/Webstore.Services/Mapping/BrandMapper.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WebStore.Domain.DTO.Products; +using WebStore.Domain.Entities; + +namespace Webstore.Services.Mapping +{ + public static class BrandMapper + { + public static BrandDTO ToDTO(this Brand Brand) => Brand is null ? null + : new BrandDTO + { + Id = Brand.Id, + Name = Brand.Name, + Order = Brand.Order, + ProductsCount = Brand.Products.Count(), + }; + public static Brand FromDTO(this BrandDTO Brand) => Brand is null ? null + : new Brand + { + Id = Brand.Id, + Name = Brand.Name, + Order = Brand.Order + }; + public static IEnumerable ToDTO(this IEnumerable Brands) => Brands.Select(ToDTO); + + public static IEnumerable FromDTO(this IEnumerable Brands) => Brands.Select(FromDTO); + + } +} diff --git a/Services/Webstore.Services/Mapping/CategoryMapper.cs b/Services/Webstore.Services/Mapping/CategoryMapper.cs new file mode 100644 index 0000000..813a4d1 --- /dev/null +++ b/Services/Webstore.Services/Mapping/CategoryMapper.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using WebStore.Domain.DTO.Products; +using WebStore.Domain.Entities; + +namespace Webstore.Services.Mapping +{ + public static class CategoryMapper + { + public static CategoryDTO ToDTO(this Category Category) => Category is null ? null + : new CategoryDTO + { + Id = Category.Id, + Name = Category.Name, + Order = Category.Order, + ParentId = Category.ParentId, + ProductsCount = Category.Products.Count() + }; + public static Category FromDTO(this CategoryDTO Category) => Category is null ? null + : new Category + { + Id = Category.Id, + Name = Category.Name, + Order = Category.Order, + ParentId = Category.ParentId + }; + public static IEnumerable ToDTO(this IEnumerable Categories) => Categories.Select(ToDTO); + + public static IEnumerable FromDTO(this IEnumerable Categories) => Categories.Select(FromDTO); + } +} diff --git a/Services/Webstore.Services/Mapping/ProductMapper.cs b/Services/Webstore.Services/Mapping/ProductMapper.cs index 9ecb34b..85af67a 100644 --- a/Services/Webstore.Services/Mapping/ProductMapper.cs +++ b/Services/Webstore.Services/Mapping/ProductMapper.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using WebStore.Domain.DTO.Products; using WebStore.Domain.Entities; using WebStore.Domain.ViewModels; @@ -21,9 +22,43 @@ public static class ProductMapper ImageUrl = p.ImageUrl, Name = p.Name, Order = p.Order, - Price = p.Price + Price = p.Price }; public static IEnumerable ToView(this IEnumerable p) => p.Select(ToView); + + public static ProductDTO ToDTO(this Product product) => product is null ? null + : new ProductDTO + { + Id = product.Id, + Name = product.Name, + Order = product.Order, + Price = product.Price, + ImageUrl = product.ImageUrl, + Brand = product.Brand.ToDTO(), + Category = product.Category.ToDTO(), + Description = product.Description, + Discount = product.Discount + }; + + public static Product FromDTO(this ProductDTO Product) => Product is null ? null + : new Product + { + Id = Product.Id, + Name = Product.Name, + Order = Product.Order, + Price = Product.Price, + ImageUrl = Product.ImageUrl, + Description = Product.Description, + Discount = Product.Discount, + Brand = Product.Brand.FromDTO(), + Category = Product.Category.FromDTO(), + BrandId = Product.Brand.Id, + CategoryId = Product.Category.Id + + }; + public static IEnumerable ToDTO(this IEnumerable products) => products.Select(ToDTO); + + public static IEnumerable FromDTO(this IEnumerable products) => products.Select(FromDTO); } } From 3ebd6ad1c45e7de9b5998d15238bba60273ff3fe Mon Sep 17 00:00:00 2001 From: dmitry Date: Wed, 3 Feb 2021 12:18:19 +0500 Subject: [PATCH 18/22] =?UTF-8?q?=D0=BF=D0=BE=D0=BC=D0=B5=D0=BD=D1=8F?= =?UTF-8?q?=D0=BB=D0=B8=20=D0=B8=D0=BD=D1=82=D0=B5=D1=80=D1=84=D0=B5=D0=B9?= =?UTF-8?q?=D1=81=20=D0=BD=D0=B0=20DTO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Services/IProductData.cs | 13 ++++++----- .../InCookies/InCookiesCartService.cs | 2 +- .../Products/InMemoryProductsData.cs | 16 ++++++++------ .../Products/InSql/InSqIProductData.cs | 22 ++++++++++--------- UI/WebStore/Controllers/ShopController.cs | 9 ++++---- 5 files changed, 33 insertions(+), 29 deletions(-) diff --git a/Services/Webstore.Interfaces/Services/IProductData.cs b/Services/Webstore.Interfaces/Services/IProductData.cs index b6e46b5..20811fd 100644 --- a/Services/Webstore.Interfaces/Services/IProductData.cs +++ b/Services/Webstore.Interfaces/Services/IProductData.cs @@ -1,21 +1,22 @@ using System.Collections.Generic; using WebStore.Domain; +using WebStore.Domain.DTO.Products; using WebStore.Domain.Entities; namespace Webstore.Interfaces.Services { public interface IProductData { - IEnumerable GetСategories(); + IEnumerable GetСategories(); - Category GetСategoriesById(int id); + CategoryDTO GetСategoriesById(int id); - IEnumerable GetBrands(); + IEnumerable GetBrands(); - Brand GetBrandsById(int id); + BrandDTO GetBrandsById(int id); - IEnumerable GetProducts(ProductFilter Filter = null); + IEnumerable GetProducts(ProductFilter Filter = null); - Product GetProductById(int id); + ProductDTO GetProductById(int id); } } diff --git a/Services/Webstore.Services/Products/InCookies/InCookiesCartService.cs b/Services/Webstore.Services/Products/InCookies/InCookiesCartService.cs index dc77a4b..eb32380 100644 --- a/Services/Webstore.Services/Products/InCookies/InCookiesCartService.cs +++ b/Services/Webstore.Services/Products/InCookies/InCookiesCartService.cs @@ -113,7 +113,7 @@ public CartViewModel TransformFromCart() Ids = Cart.Items.Select(item => item.ProductId).ToArray() }); - var product_view_models = products.ToView().ToDictionary(p => p.Id); + var product_view_models = products.FromDTO().ToView().ToDictionary(p => p.Id); return new CartViewModel { diff --git a/Services/Webstore.Services/Products/InMemoryProductsData.cs b/Services/Webstore.Services/Products/InMemoryProductsData.cs index e179639..e042302 100644 --- a/Services/Webstore.Services/Products/InMemoryProductsData.cs +++ b/Services/Webstore.Services/Products/InMemoryProductsData.cs @@ -6,17 +6,19 @@ using WebStore.Domain; using WebStore.Domain.Entities; using Webstore.Services.Data; +using WebStore.Domain.DTO.Products; +using Webstore.Services.Mapping; namespace Webstore.Services.Products { [Obsolete("Класс устарел и не реализует необходимые методы")] public class InMemoryProductsData : IProductData { - public IEnumerable GetBrands() => TestDB.Brands; + public IEnumerable GetBrands() => TestDB.Brands.ToDTO(); - public IEnumerable GetСategories() => TestDB.Сategories; + public IEnumerable GetСategories() => TestDB.Сategories.ToDTO(); - public IEnumerable GetProducts(ProductFilter Filter = null) + public IEnumerable GetProducts(ProductFilter Filter = null) { var query = TestDB.Products; @@ -24,20 +26,20 @@ public IEnumerable GetProducts(ProductFilter Filter = null) query = query.Where(product => product.CategoryId == category_id).ToList(); if (Filter?.BrandId is { } brand_id) query = query.Where(product => product.BrandId == brand_id).ToList(); - return query; + return query.ToDTO(); } - public Product GetProductById(int id) + public ProductDTO GetProductById(int id) { throw new NotImplementedException(); } - public Category GetСategoriesById(int id) + public CategoryDTO GetСategoriesById(int id) { throw new NotImplementedException(); } - public Brand GetBrandsById(int id) + public BrandDTO GetBrandsById(int id) { throw new NotImplementedException(); } diff --git a/Services/Webstore.Services/Products/InSql/InSqIProductData.cs b/Services/Webstore.Services/Products/InSql/InSqIProductData.cs index c8f81c7..e8fc7cc 100644 --- a/Services/Webstore.Services/Products/InSql/InSqIProductData.cs +++ b/Services/Webstore.Services/Products/InSql/InSqIProductData.cs @@ -7,6 +7,8 @@ using Webstore.Interfaces.Services; using WebStore.Domain; using WebStore.Domain.Entities; +using Webstore.Services.Mapping; +using WebStore.Domain.DTO.Products; namespace Webstore.Services.Products.InSql { @@ -19,19 +21,19 @@ public InSqIProductData(WebStoreDB db) _db = db; } - public IEnumerable GetBrands() => _db.Brands.Include(brand => brand.Products); + public IEnumerable GetBrands() => _db.Brands.Include(brand => brand.Products).ToDTO(); - public Brand GetBrandsById(int id) + public BrandDTO GetBrandsById(int id) { - return _db.Brands.Include(brand => brand.Products).FirstOrDefault(brand => brand.Id == id); + return _db.Brands.Include(brand => brand.Products).FirstOrDefault(brand => brand.Id == id).ToDTO(); } - public Product GetProductById(int id) + public ProductDTO GetProductById(int id) { - return _db.Products.Include(p => p.Brand).Include(p => p.Category).FirstOrDefault(p => p.Id == id); + return _db.Products.Include(p => p.Brand).Include(p => p.Category).FirstOrDefault(p => p.Id == id).ToDTO(); } - public IEnumerable GetProducts(ProductFilter Filter = null) + public IEnumerable GetProducts(ProductFilter Filter = null) { IQueryable query = _db.Products.Include(p => p.Category).Include(p => p.Brand); @@ -48,14 +50,14 @@ public IEnumerable GetProducts(ProductFilter Filter = null) query = query.Where(product => product.CategoryId == Filter.СategoryId); } - return query; + return query.AsEnumerable().ToDTO(); } - public IEnumerable GetСategories() => _db.Categories.Include(category => category.Products); + public IEnumerable GetСategories() => _db.Categories.Include(category => category.Products).ToDTO(); - public Category GetСategoriesById(int id) + public CategoryDTO GetСategoriesById(int id) { - return _db.Categories.Include(category => category.Products).FirstOrDefault(category => category.Id == id); + return _db.Categories.Include(category => category.Products).FirstOrDefault(category => category.Id == id).ToDTO(); } } } diff --git a/UI/WebStore/Controllers/ShopController.cs b/UI/WebStore/Controllers/ShopController.cs index 334b6bc..2a530af 100644 --- a/UI/WebStore/Controllers/ShopController.cs +++ b/UI/WebStore/Controllers/ShopController.cs @@ -5,7 +5,6 @@ using WebStore.Domain; using WebStore.Domain.ViewModels; using WebStore.Domain.Entities; -using WebStore.Domain.ViewModels; using Webstore.Interfaces.Services; using Webstore.Services.Mapping; @@ -24,9 +23,9 @@ public IActionResult Index(int? BrandId, int? CategoryID) СategoryId = CategoryID, }; - var productc = _ProductData.GetProducts(filter); - var brends = _ProductData.GetBrands(); - var categories = _ProductData.GetСategories(); + var productc = _ProductData.GetProducts(filter).FromDTO(); + var brends = _ProductData.GetBrands().FromDTO(); + var categories = _ProductData.GetСategories().FromDTO(); @@ -73,7 +72,7 @@ private IEnumerable Categories(IEnumerable Icateg } public IActionResult Product(int id) { - var product = _ProductData.GetProductById(id); + var product = _ProductData.GetProductById(id).FromDTO(); if (product is null) return NotFound(); return View(product.ToView()); From b89c68ea54ceb8e6c8749ca93ef7f6a3480e0ef8 Mon Sep 17 00:00:00 2001 From: dmitry Date: Wed, 3 Feb 2021 12:34:27 +0500 Subject: [PATCH 19/22] =?UTF-8?q?=D0=BF=D0=BE=D0=B4=D0=BA=D0=BB=D1=8E?= =?UTF-8?q?=D1=87=D0=B8=D0=BB=D0=B8=20=D0=BA=D0=BB=D0=B8=D0=B5=D0=BD=D1=82?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D0=B4=D1=83=D0=BA=D1=82=D0=BE=D0=B2=20?= =?UTF-8?q?=D0=BA=20=D0=BE=D1=81=D0=BD=D0=BE=D0=B2=D0=BD=D0=BE=D0=BC=D1=83?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Products/ProductsClient.cs | 55 +++++++++++++++++++ .../Controllers/ProductsApiController.cs | 2 +- .../Services/IProductDataDTO.cs | 22 -------- Services/Webstore.Interfaces/WebAPI.cs | 16 ++++++ UI/WebStore/Startup.cs | 4 +- 5 files changed, 75 insertions(+), 24 deletions(-) create mode 100644 Services/WebStore.Client/Products/ProductsClient.cs delete mode 100644 Services/Webstore.Interfaces/Services/IProductDataDTO.cs create mode 100644 Services/Webstore.Interfaces/WebAPI.cs diff --git a/Services/WebStore.Client/Products/ProductsClient.cs b/Services/WebStore.Client/Products/ProductsClient.cs new file mode 100644 index 0000000..12d4d38 --- /dev/null +++ b/Services/WebStore.Client/Products/ProductsClient.cs @@ -0,0 +1,55 @@ +using Microsoft.Extensions.Configuration; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Text; +using System.Threading.Tasks; +using Webstore.Interfaces; +using Webstore.Interfaces.Services; +using WebStore.Client.Base; +using WebStore.Domain; +using WebStore.Domain.DTO.Products; + +namespace WebStore.Client.Products +{ + public class ProductsClient : BaseClient, IProductData + { + public ProductsClient(IConfiguration Configuration) : base(Configuration, WebAPI.Products) + { + } + + public IEnumerable GetBrands() + { + return Get>($"{Address}/brands"); + } + + public BrandDTO GetBrandsById(int id) + { + return Get($"{Address}/brands/{id}"); + } + + public ProductDTO GetProductById(int id) + { + return Get($"{Address}/{id}"); + } + + public IEnumerable GetProducts(ProductFilter Filter = null) + { + return Post(Address, Filter ?? new ProductFilter()) + .Content + .ReadAsAsync>() + .Result; + } + + public IEnumerable GetСategories() + { + return Get>($"{Address}/categories"); + } + + public CategoryDTO GetСategoriesById(int id) + { + return Get($"{Address}/categories/{id}"); + } + } +} diff --git a/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs b/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs index a2cda0d..35251c8 100644 --- a/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs +++ b/Services/WebStore.ServiceHosting/Controllers/ProductsApiController.cs @@ -14,7 +14,7 @@ namespace WebStore.ServiceHosting.Controllers { [Route("api/products")] [ApiController] - public class ProductsApiController : ControllerBase, IProductDataDTO + public class ProductsApiController : ControllerBase, IProductData { private readonly IProductData _db; private readonly ILogger _Logger; diff --git a/Services/Webstore.Interfaces/Services/IProductDataDTO.cs b/Services/Webstore.Interfaces/Services/IProductDataDTO.cs deleted file mode 100644 index e1efe0a..0000000 --- a/Services/Webstore.Interfaces/Services/IProductDataDTO.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; -using WebStore.Domain; -using WebStore.Domain.DTO.Products; -using WebStore.Domain.Entities; - -namespace Webstore.Interfaces.Services -{ - public interface IProductDataDTO - { - IEnumerable GetСategories(); - - CategoryDTO GetСategoriesById(int id); - - IEnumerable GetBrands(); - - BrandDTO GetBrandsById(int id); - - IEnumerable GetProducts(ProductFilter Filter = null); - - ProductDTO GetProductById(int id); - } -} diff --git a/Services/Webstore.Interfaces/WebAPI.cs b/Services/Webstore.Interfaces/WebAPI.cs new file mode 100644 index 0000000..dcc7edd --- /dev/null +++ b/Services/Webstore.Interfaces/WebAPI.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Webstore.Interfaces +{ + public static class WebAPI + { + public const string Products = "api/products"; + public const string Values = "api/values"; + public const string Employees = "api/employees"; + public const string Orders = "api/orders"; + } +} diff --git a/UI/WebStore/Startup.cs b/UI/WebStore/Startup.cs index dd8472a..8499276 100644 --- a/UI/WebStore/Startup.cs +++ b/UI/WebStore/Startup.cs @@ -20,6 +20,7 @@ using WebStore.Client.Values; using WebStore.Interfaces.TestAPI; using WebStore.Client.Employees; +using WebStore.Client.Products; namespace WebStore { @@ -74,7 +75,8 @@ public void ConfigureServices(IServiceCollection services) services.AddControllersWithViews().AddRazorRuntimeCompilation(); services.AddSingleton(); //services.AddTransient(); - services.AddTransient(); + //services.AddTransient(); + services.AddTransient(); services.AddSingleton(); services.AddScoped(); services.AddScoped(); From bac6c607954d3dccc0e0cc4efb5b3c3b054dda4d Mon Sep 17 00:00:00 2001 From: dmitry Date: Wed, 3 Feb 2021 16:28:07 +0500 Subject: [PATCH 20/22] =?UTF-8?q?=D0=B7=D0=B0=D0=BF=D0=B8=D0=BB=D0=B8?= =?UTF-8?q?=D0=BB=D0=B8=20=D0=B7=D0=B0=D0=BA=D0=B0=D0=B7=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Common/WebStore.Domain/DTO/Orders/OrderDTO.cs | 18 ++++++++ .../WebStore.Client/Orders/OrdersClient.cs | 35 ++++++++++++++ .../Controllers/OrdersApiController.cs | 46 +++++++++++++++++++ .../Services/IOrderService.cs | 7 +-- .../Webstore.Services/Mapping/OrderMapper.cs | 38 +++++++++++++++ .../Products/InSql/SqlOrderService.cs | 39 ++++++++-------- UI/WebStore/Controllers/CartController.cs | 13 +++++- 7 files changed, 170 insertions(+), 26 deletions(-) create mode 100644 Common/WebStore.Domain/DTO/Orders/OrderDTO.cs create mode 100644 Services/WebStore.Client/Orders/OrdersClient.cs create mode 100644 Services/WebStore.ServiceHosting/Controllers/OrdersApiController.cs create mode 100644 Services/Webstore.Services/Mapping/OrderMapper.cs diff --git a/Common/WebStore.Domain/DTO/Orders/OrderDTO.cs b/Common/WebStore.Domain/DTO/Orders/OrderDTO.cs new file mode 100644 index 0000000..0540696 --- /dev/null +++ b/Common/WebStore.Domain/DTO/Orders/OrderDTO.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using WebStore.Domain.ViewModels; + +namespace WebStore.Domain.DTO.Orders +{ + public record OrderItemDTO(int Id, decimal Price, int Quantity); + + public record OrderDTO( + int Id, + string Name, + string Phone, + string Address, + DateTime Date, + IEnumerable Items); + + public record CreateOrderModel(OrderViewModel Order, IList Items); +} diff --git a/Services/WebStore.Client/Orders/OrdersClient.cs b/Services/WebStore.Client/Orders/OrdersClient.cs new file mode 100644 index 0000000..cb0e6dc --- /dev/null +++ b/Services/WebStore.Client/Orders/OrdersClient.cs @@ -0,0 +1,35 @@ +using System.Collections.Generic; +using System.Net.Http; +using System.Threading.Tasks; +using Microsoft.Extensions.Configuration; +using Microsoft.Extensions.Logging; +using Webstore.Interfaces; +using Webstore.Interfaces.Services; +using WebStore.Client.Base; +using WebStore.Domain.DTO.Orders; +using WebStore.Domain.ViewModels; +using WebStore.Interfaces; + +namespace WebStore.Client.Orders +{ + public class OrdersClient : BaseClient, IOrderService + { + private readonly ILogger _Logger; + public OrdersClient(IConfiguration Configuration, ILogger Logger) + : base(Configuration, WebAPI.Orders) => + _Logger = Logger; + + + public async Task> GetUserOrders(string UserName) => + await GetAsync>($"{Address}/user/{UserName}"); + + public async Task GetOrderById(int id) => + await GetAsync($"{Address}/{id}"); + + public async Task CreateOrder(string UserName, CreateOrderModel OrderModel) + { + var response = await PostAsync($"{Address}/{UserName}", OrderModel); + return await response.Content.ReadAsAsync(); + } + } +} diff --git a/Services/WebStore.ServiceHosting/Controllers/OrdersApiController.cs b/Services/WebStore.ServiceHosting/Controllers/OrdersApiController.cs new file mode 100644 index 0000000..151c665 --- /dev/null +++ b/Services/WebStore.ServiceHosting/Controllers/OrdersApiController.cs @@ -0,0 +1,46 @@ +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.Extensions.Logging; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Webstore.Interfaces; +using Webstore.Interfaces.Services; +using WebStore.Domain.DTO.Orders; +using WebStore.Domain.Entities.Orders; +using WebStore.Domain.ViewModels; + +namespace WebStore.ServiceHosting.Controllers +{ + [Route(WebAPI.Orders)] + [ApiController] + public class OrdersApiController : ControllerBase, IOrderService + { + private readonly IOrderService orderService; + private readonly ILogger logger; + + public OrdersApiController(IOrderService orderService, ILogger Logger) + { + this.orderService = orderService; + logger = Logger; + } + + [HttpPost("{UserName}")] + public async Task CreateOrder(string UserName, CreateOrderModel OrderModel) + { + return await orderService.CreateOrder(UserName, OrderModel); + } + + [HttpGet("{id}")] + public async Task GetOrderById(int id) + { + return await orderService.GetOrderById(id); + } + [HttpGet("user/{UserName}")] + public async Task> GetUserOrders(string UserName) + { + return await orderService.GetUserOrders(UserName); + } + } +} diff --git a/Services/Webstore.Interfaces/Services/IOrderService.cs b/Services/Webstore.Interfaces/Services/IOrderService.cs index 024e0c0..fba8b44 100644 --- a/Services/Webstore.Interfaces/Services/IOrderService.cs +++ b/Services/Webstore.Interfaces/Services/IOrderService.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using System.Threading.Tasks; +using WebStore.Domain.DTO.Orders; using WebStore.Domain.Entities.Orders; using WebStore.Domain.ViewModels; @@ -7,10 +8,10 @@ namespace Webstore.Interfaces.Services { public interface IOrderService { - Task> GetUserOrders(string UserName); + Task> GetUserOrders(string UserName); - Task GetOrderById(int id); + Task GetOrderById(int id); - Task CreateOrder(string UserName, CartViewModel Cart, OrderViewModel OrderModel); + Task CreateOrder(string UserName, CreateOrderModel OrderModel); } } diff --git a/Services/Webstore.Services/Mapping/OrderMapper.cs b/Services/Webstore.Services/Mapping/OrderMapper.cs new file mode 100644 index 0000000..e90ae88 --- /dev/null +++ b/Services/Webstore.Services/Mapping/OrderMapper.cs @@ -0,0 +1,38 @@ +using System.Linq; +using WebStore.Domain.DTO.Orders; +using WebStore.Domain.Entities.Orders; + +namespace WebStore.Services.Mapping +{ + public static class OrderMapper + { + public static OrderItemDTO ToDTO(this OrderItem Item) => Item is null + ? null + : new OrderItemDTO(Item.Id, Item.Price, Item.Quantity); + + public static OrderItem FromDTO(this OrderItemDTO Item) => Item is null + ? null + : new OrderItem + { + Id = Item.Id, + Price = Item.Price, + Quantity = Item.Quantity + }; + + public static OrderDTO ToDTO(this Order Order) => Order is null + ? null + : new OrderDTO(Order.Id, Order.Name, Order.Phone, Order.Address, Order.Date, Order.Items.Select(ToDTO)); + + public static Order FromDTO(this OrderDTO Order) => Order is null + ? null + : new Order + { + Id = Order.Id, + Name = Order.Name, + Phone = Order.Phone, + Address = Order.Address, + Date = Order.Date, + Items = Order.Items.Select(FromDTO).ToList() + }; + } +} diff --git a/Services/Webstore.Services/Products/InSql/SqlOrderService.cs b/Services/Webstore.Services/Products/InSql/SqlOrderService.cs index 30be498..9f5876d 100644 --- a/Services/Webstore.Services/Products/InSql/SqlOrderService.cs +++ b/Services/Webstore.Services/Products/InSql/SqlOrderService.cs @@ -7,9 +7,11 @@ using Microsoft.EntityFrameworkCore; using Webstore.DAL.Context; using Webstore.Interfaces.Services; +using WebStore.Domain.DTO.Orders; using WebStore.Domain.Entities.Identity; using WebStore.Domain.Entities.Orders; using WebStore.Domain.ViewModels; +using WebStore.Services.Mapping; namespace Webstore.Services.Products.InSql { @@ -24,18 +26,18 @@ public SqlOrderService(WebStoreDB db, UserManager UserManager) _UserManager = UserManager; } - public async Task> GetUserOrders(string UserName) => await _db.Orders + public async Task> GetUserOrders(string UserName) => (await _db.Orders .Include(order => order.User) .Include(order => order.Items) .Where(order => order.User.UserName == UserName) - .ToArrayAsync(); + .ToArrayAsync()).Select(o => o.ToDTO()); - public async Task GetOrderById(int id) => await _db.Orders + public async Task GetOrderById(int id) => (await _db.Orders .Include(order => order.User) .Include(order => order.Items) - .FirstOrDefaultAsync(order => order.Id == id); + .FirstOrDefaultAsync(order => order.Id == id)).ToDTO(); - public async Task CreateOrder(string UserName, CartViewModel Cart, OrderViewModel OrderModel) + public async Task CreateOrder(string UserName, CreateOrderModel OrderModel) { var user = await _UserManager.FindByNameAsync(UserName); if (user is null) @@ -45,32 +47,27 @@ public async Task CreateOrder(string UserName, CartViewModel Cart, OrderV var order = new Order { - Name = OrderModel.Name, - Address = OrderModel.Address, - Phone = OrderModel.Phone, + Name = OrderModel.Order.Name, + Address = OrderModel.Order.Address, + Phone = OrderModel.Order.Phone, User = user, Date = DateTime.Now, }; - var product_ids = Cart.Items.Select(i => i.Product.Id).ToArray(); - var cart_products = await _db.Products - .Where(p => product_ids.Contains(p.Id)) - .ToArrayAsync(); + foreach (var (id, _, quantity) in OrderModel.Items) + { + var product = await _db.Products.FindAsync(id); + if (product is null) continue; - var items = - from cart_item in Cart.Items - join product in cart_products - on cart_item.Product.Id equals product.Id - select new OrderItem + var order_item = new OrderItem { Order = order, Price = product.Price, - Quantity = cart_item.Quantity, + Quantity = quantity, Product = product }; - - foreach (var order_item in items) order.Items.Add(order_item); + } await _db.Orders.AddAsync(order); @@ -78,7 +75,7 @@ on cart_item.Product.Id equals product.Id await transaction.CommitAsync(); - return order; + return order.ToDTO(); } } } diff --git a/UI/WebStore/Controllers/CartController.cs b/UI/WebStore/Controllers/CartController.cs index 6771fdc..58aa5d2 100644 --- a/UI/WebStore/Controllers/CartController.cs +++ b/UI/WebStore/Controllers/CartController.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Threading.Tasks; using Webstore.Interfaces.Services; +using WebStore.Domain.DTO.Orders; using WebStore.Domain.ViewModels; namespace WebStore.Controllers @@ -60,10 +61,18 @@ public async Task CheckOut(OrderViewModel OrderModel, [FromServic Order = OrderModel }); + var create_order_model = new CreateOrderModel( + OrderModel, + _CartService.TransformFromCart().Items + .Select(item => new OrderItemDTO( + item.Product.Id, + item.Product.Price, + item.Quantity)) + .ToList()); + var order = await OrderService.CreateOrder( User.Identity!.Name, - _CartService.TransformFromCart(), - OrderModel); + create_order_model); _CartService.Clear(); From 370adc1a3810201b7edf4d2bcc5102b6248b52c2 Mon Sep 17 00:00:00 2001 From: dmitry Date: Wed, 3 Feb 2021 17:10:13 +0500 Subject: [PATCH 21/22] =?UTF-8?q?=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=B8?= =?UTF-8?q?=D0=BB=20=D0=BF=D1=80=D0=BE=D1=84=D0=B8=D0=BB=D1=8C=20=D0=BF?= =?UTF-8?q?=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ViewModels/UserOrderViewModel.cs | 20 ++++++++++++ .../Controllers/UserProfileController.cs | 31 +++++++++++++++++++ UI/WebStore/Startup.cs | 4 ++- .../Components/UserInfo/UserInfo.cshtml | 2 +- UI/WebStore/Views/UserProfile/Index.cshtml | 8 +++++ UI/WebStore/Views/UserProfile/Orders.cshtml | 31 +++++++++++++++++++ .../UserProfile/Partial/_Index_Scripts.cshtml | 10 ++++++ .../UserProfile/Partial/_Index_Styles.cshtml | 2 ++ .../Partial/_UserProfileMenu.cshtml | 15 +++++++++ .../UserProfile/_UserProfileLayout.cshtml | 20 ++++++++++++ 10 files changed, 141 insertions(+), 2 deletions(-) create mode 100644 Common/WebStore.Domain/ViewModels/UserOrderViewModel.cs create mode 100644 UI/WebStore/Controllers/UserProfileController.cs create mode 100644 UI/WebStore/Views/UserProfile/Index.cshtml create mode 100644 UI/WebStore/Views/UserProfile/Orders.cshtml create mode 100644 UI/WebStore/Views/UserProfile/Partial/_Index_Scripts.cshtml create mode 100644 UI/WebStore/Views/UserProfile/Partial/_Index_Styles.cshtml create mode 100644 UI/WebStore/Views/UserProfile/Partial/_UserProfileMenu.cshtml create mode 100644 UI/WebStore/Views/UserProfile/_UserProfileLayout.cshtml diff --git a/Common/WebStore.Domain/ViewModels/UserOrderViewModel.cs b/Common/WebStore.Domain/ViewModels/UserOrderViewModel.cs new file mode 100644 index 0000000..e8a77fd --- /dev/null +++ b/Common/WebStore.Domain/ViewModels/UserOrderViewModel.cs @@ -0,0 +1,20 @@ +using System.ComponentModel.DataAnnotations; + +namespace WebStore.Domain.ViewModels +{ + public class UserOrderViewModel + { + public int Id { get; set; } + + [Required] + public string Name { get; set; } + + [Required] + public string Phone { get; set; } + + [Required] + public string Address { get; set; } + + public decimal TotalSum { get; set; } + } +} diff --git a/UI/WebStore/Controllers/UserProfileController.cs b/UI/WebStore/Controllers/UserProfileController.cs new file mode 100644 index 0000000..57d0d57 --- /dev/null +++ b/UI/WebStore/Controllers/UserProfileController.cs @@ -0,0 +1,31 @@ +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Webstore.Interfaces.Services; +using WebStore.Domain.ViewModels; + +namespace WebStore.Controllers +{ + [Authorize] + public class UserProfileController : Controller + { + public IActionResult Index() => View(); + + public async Task Orders([FromServices] IOrderService OrderService) + { + var orders = await OrderService.GetUserOrders(User.Identity!.Name); + + return View(orders.Select(order => new UserOrderViewModel + { + Id = order.Id, + Name = order.Name, + Phone = order.Phone, + Address = order.Address, + TotalSum = order.Items.Sum(item => item.Price * item.Quantity) + })); + } + } +} diff --git a/UI/WebStore/Startup.cs b/UI/WebStore/Startup.cs index 8499276..686f987 100644 --- a/UI/WebStore/Startup.cs +++ b/UI/WebStore/Startup.cs @@ -21,6 +21,7 @@ using WebStore.Interfaces.TestAPI; using WebStore.Client.Employees; using WebStore.Client.Products; +using WebStore.Client.Orders; namespace WebStore { @@ -79,7 +80,8 @@ public void ConfigureServices(IServiceCollection services) services.AddTransient(); services.AddSingleton(); services.AddScoped(); - services.AddScoped(); + //services.AddScoped(); + services.AddScoped(); services.AddScoped(); } diff --git a/UI/WebStore/Views/Shared/Components/UserInfo/UserInfo.cshtml b/UI/WebStore/Views/Shared/Components/UserInfo/UserInfo.cshtml index e4ffcc0..eaa69a3 100644 --- a/UI/WebStore/Views/Shared/Components/UserInfo/UserInfo.cshtml +++ b/UI/WebStore/Views/Shared/Components/UserInfo/UserInfo.cshtml @@ -1,5 +1,5 @@ @using WebStore.Domain.Entities.Identity - + @if (User.IsInRole(Role.Administrator)) { diff --git a/UI/WebStore/Views/UserProfile/Index.cshtml b/UI/WebStore/Views/UserProfile/Index.cshtml new file mode 100644 index 0000000..82d9a69 --- /dev/null +++ b/UI/WebStore/Views/UserProfile/Index.cshtml @@ -0,0 +1,8 @@ + +@{ + Layout = "_UserProfileLayout"; + ViewData["Title"] = "Профиль пользователя"; +} + +

Профиль пользователя

+ diff --git a/UI/WebStore/Views/UserProfile/Orders.cshtml b/UI/WebStore/Views/UserProfile/Orders.cshtml new file mode 100644 index 0000000..9dfa990 --- /dev/null +++ b/UI/WebStore/Views/UserProfile/Orders.cshtml @@ -0,0 +1,31 @@ +@model IEnumerable +@{ + Layout = "_UserProfileLayout"; + ViewData["Title"] = "Заказы"; +} + + + + + + + + + + + + + @{ var i = 1; } + @foreach (var order in Model) + { + + + + + + + + } + +
ИмяАдресТелефонСумма
@(i++)@order.Name@order.Address@order.Phone@order.TotalSum
+ diff --git a/UI/WebStore/Views/UserProfile/Partial/_Index_Scripts.cshtml b/UI/WebStore/Views/UserProfile/Partial/_Index_Scripts.cshtml new file mode 100644 index 0000000..f5b2aed --- /dev/null +++ b/UI/WebStore/Views/UserProfile/Partial/_Index_Scripts.cshtml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/UI/WebStore/Views/UserProfile/Partial/_Index_Styles.cshtml b/UI/WebStore/Views/UserProfile/Partial/_Index_Styles.cshtml new file mode 100644 index 0000000..40166d6 --- /dev/null +++ b/UI/WebStore/Views/UserProfile/Partial/_Index_Styles.cshtml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/UI/WebStore/Views/UserProfile/Partial/_UserProfileMenu.cshtml b/UI/WebStore/Views/UserProfile/Partial/_UserProfileMenu.cshtml new file mode 100644 index 0000000..f7dbebb --- /dev/null +++ b/UI/WebStore/Views/UserProfile/Partial/_UserProfileMenu.cshtml @@ -0,0 +1,15 @@ +
+ +
+ +
+ +
+ +
+ +
\ No newline at end of file diff --git a/UI/WebStore/Views/UserProfile/_UserProfileLayout.cshtml b/UI/WebStore/Views/UserProfile/_UserProfileLayout.cshtml new file mode 100644 index 0000000..9da4ea5 --- /dev/null +++ b/UI/WebStore/Views/UserProfile/_UserProfileLayout.cshtml @@ -0,0 +1,20 @@ +@section Styles { + +} +@section Scripts { + +} +@{ + Layout = "_Layout"; +} + +
+
+
+ +
+
+ @RenderBody() +
+
+
\ No newline at end of file From f133052de919d9f67d2f34331b93523b4f1b2a57 Mon Sep 17 00:00:00 2001 From: dmitry Date: Sat, 30 Jan 2021 17:21:26 +0500 Subject: [PATCH 22/22] =?UTF-8?q?=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D0=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- UI/WebStore/Startup.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/UI/WebStore/Startup.cs b/UI/WebStore/Startup.cs index 686f987..1a11475 100644 --- a/UI/WebStore/Startup.cs +++ b/UI/WebStore/Startup.cs @@ -75,6 +75,7 @@ public void ConfigureServices(IServiceCollection services) services.AddControllersWithViews().AddRazorRuntimeCompilation(); services.AddSingleton(); + //services.AddTransient(); //services.AddTransient(); services.AddTransient();