From 5e7de1617e8c64b3a37d68046bad03e4f0ddb574 Mon Sep 17 00:00:00 2001 From: Sumit Ghosh Date: Wed, 20 Oct 2021 16:04:59 +0530 Subject: [PATCH] Included file scope namespaces for all files --- src/Web/WebMVC/AppSettings.cs | 49 ++- .../WebMVC/Controllers/AccountController.cs | 75 ++--- src/Web/WebMVC/Controllers/CartController.cs | 122 ++++--- .../WebMVC/Controllers/CatalogController.cs | 60 ++-- src/Web/WebMVC/Controllers/ErrorController.cs | 9 +- src/Web/WebMVC/Controllers/OrderController.cs | 117 ++++--- .../Controllers/OrderManagementController.cs | 53 ++- src/Web/WebMVC/Controllers/TestController.cs | 81 ++--- .../WebMVC/Extensions/HttpClientExtensions.cs | 45 ++- .../WebMVC/Extensions/SessionExtensions.cs | 6 +- src/Web/WebMVC/Infrastructure/API.cs | 121 ++++--- ...ttpClientAuthorizationDelegatingHandler.cs | 65 ++-- .../HttpClientRequestIdDelegatingHandler.cs | 34 +- .../WebMVC/Infrastructure/WebContextSeed.cs | 124 ++++--- src/Web/WebMVC/Program.cs | 11 +- src/Web/WebMVC/Services/BasketService.cs | 188 +++++------ src/Web/WebMVC/Services/CatalogService.cs | 121 ++++--- src/Web/WebMVC/Services/IBasketService.cs | 24 +- src/Web/WebMVC/Services/ICatalogService.cs | 16 +- src/Web/WebMVC/Services/IIdentityParser.cs | 9 +- src/Web/WebMVC/Services/IOrderingService.cs | 25 +- src/Web/WebMVC/Services/IdentityParser.cs | 57 ++-- .../WebMVC/Services/ModelDTOs/BasketDTO.cs | 51 ++- .../WebMVC/Services/ModelDTOs/LocationDTO.cs | 11 +- src/Web/WebMVC/Services/ModelDTOs/OrderDTO.cs | 13 +- .../Services/ModelDTOs/OrderProcessAction.cs | 27 +- src/Web/WebMVC/Services/OrderingService.cs | 223 ++++++------- src/Web/WebMVC/Startup.cs | 310 ++++++++---------- src/Web/WebMVC/ViewComponents/Cart.cs | 45 ++- src/Web/WebMVC/ViewComponents/CartList.cs | 39 +-- .../ViewModels/Annotations/CardExpiration.cs | 42 ++- .../Annotations/LatitudeCoordinate.cs | 26 +- .../Annotations/LongitudeCoordinate.cs | 26 +- src/Web/WebMVC/ViewModels/ApplicationUser.cs | 46 ++- src/Web/WebMVC/ViewModels/Basket.cs | 27 +- src/Web/WebMVC/ViewModels/BasketItem.cs | 21 +- src/Web/WebMVC/ViewModels/Campaign.cs | 17 +- src/Web/WebMVC/ViewModels/CampaignItem.cs | 23 +- .../CartViewModels/IndexViewModel.cs | 11 +- src/Web/WebMVC/ViewModels/Catalog.cs | 15 +- src/Web/WebMVC/ViewModels/CatalogItem.cs | 27 +- .../CatalogViewModels/IndexViewModel.cs | 21 +- .../Converters/NumberToStringConverter.cs | 42 +-- src/Web/WebMVC/ViewModels/Header.cs | 13 +- src/Web/WebMVC/ViewModels/Order.cs | 168 +++++----- src/Web/WebMVC/ViewModels/OrderItem.cs | 19 +- .../ViewModels/Pagination/PaginationInfo.cs | 19 +- 47 files changed, 1213 insertions(+), 1481 deletions(-) diff --git a/src/Web/WebMVC/AppSettings.cs b/src/Web/WebMVC/AppSettings.cs index 17a37b1fc..ae0a02650 100644 --- a/src/Web/WebMVC/AppSettings.cs +++ b/src/Web/WebMVC/AppSettings.cs @@ -1,30 +1,29 @@ -namespace Microsoft.eShopOnContainers.WebMVC +namespace Microsoft.eShopOnContainers.WebMVC; + +public class AppSettings { - public class AppSettings - { - //public Connectionstrings ConnectionStrings { get; set; } - public string PurchaseUrl { get; set; } - public string SignalrHubUrl { get; set; } - public bool ActivateCampaignDetailFunction { get; set; } - public Logging Logging { get; set; } - public bool UseCustomizationData { get; set; } - } + //public Connectionstrings ConnectionStrings { get; set; } + public string PurchaseUrl { get; set; } + public string SignalrHubUrl { get; set; } + public bool ActivateCampaignDetailFunction { get; set; } + public Logging Logging { get; set; } + public bool UseCustomizationData { get; set; } +} - public class Connectionstrings - { - public string DefaultConnection { get; set; } - } +public class Connectionstrings +{ + public string DefaultConnection { get; set; } +} - public class Logging - { - public bool IncludeScopes { get; set; } - public Loglevel LogLevel { get; set; } - } +public class Logging +{ + public bool IncludeScopes { get; set; } + public Loglevel LogLevel { get; set; } +} - public class Loglevel - { - public string Default { get; set; } - public string System { get; set; } - public string Microsoft { get; set; } - } +public class Loglevel +{ + public string Default { get; set; } + public string System { get; set; } + public string Microsoft { get; set; } } diff --git a/src/Web/WebMVC/Controllers/AccountController.cs b/src/Web/WebMVC/Controllers/AccountController.cs index fba04f26d..e2a191bd2 100644 --- a/src/Web/WebMVC/Controllers/AccountController.cs +++ b/src/Web/WebMVC/Controllers/AccountController.cs @@ -1,53 +1,42 @@ -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Authentication.Cookies; -using Microsoft.AspNetCore.Authentication.OpenIdConnect; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.Extensions.Logging; -using System; -using System.Security.Claims; -using System.Threading.Tasks; - -namespace Microsoft.eShopOnContainers.WebMVC.Controllers +namespace Microsoft.eShopOnContainers.WebMVC.Controllers; + +[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] +public class AccountController : Controller { + private readonly ILogger _logger; + + public AccountController(ILogger logger) + { + _logger = logger ?? throw new ArgumentNullException(nameof(logger)); + } + [Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] - public class AccountController : Controller + public async Task SignIn(string returnUrl) { - private readonly ILogger _logger; + var user = User as ClaimsPrincipal; + var token = await HttpContext.GetTokenAsync("access_token"); - public AccountController(ILogger logger) - { - _logger = logger ?? throw new ArgumentNullException(nameof(logger)); - } + _logger.LogInformation("----- User {@User} authenticated into {AppName}", user, Program.AppName); - [Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] - public async Task SignIn(string returnUrl) + if (token != null) { - var user = User as ClaimsPrincipal; - var token = await HttpContext.GetTokenAsync("access_token"); - - _logger.LogInformation("----- User {@User} authenticated into {AppName}", user, Program.AppName); - - if (token != null) - { - ViewData["access_token"] = token; - } - - // "Catalog" because UrlHelper doesn't support nameof() for controllers - // https://github.com/aspnet/Mvc/issues/5853 - return RedirectToAction(nameof(CatalogController.Index), "Catalog"); + ViewData["access_token"] = token; } - public async Task Signout() - { - await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); - await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme); - - // "Catalog" because UrlHelper doesn't support nameof() for controllers - // https://github.com/aspnet/Mvc/issues/5853 - var homeUrl = Url.Action(nameof(CatalogController.Index), "Catalog"); - return new SignOutResult(OpenIdConnectDefaults.AuthenticationScheme, - new AspNetCore.Authentication.AuthenticationProperties { RedirectUri = homeUrl }); - } + // "Catalog" because UrlHelper doesn't support nameof() for controllers + // https://github.com/aspnet/Mvc/issues/5853 + return RedirectToAction(nameof(CatalogController.Index), "Catalog"); + } + + public async Task Signout() + { + await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); + await HttpContext.SignOutAsync(OpenIdConnectDefaults.AuthenticationScheme); + + // "Catalog" because UrlHelper doesn't support nameof() for controllers + // https://github.com/aspnet/Mvc/issues/5853 + var homeUrl = Url.Action(nameof(CatalogController.Index), "Catalog"); + return new SignOutResult(OpenIdConnectDefaults.AuthenticationScheme, + new AspNetCore.Authentication.AuthenticationProperties { RedirectUri = homeUrl }); } } diff --git a/src/Web/WebMVC/Controllers/CartController.cs b/src/Web/WebMVC/Controllers/CartController.cs index d7e577c25..fc506ec43 100644 --- a/src/Web/WebMVC/Controllers/CartController.cs +++ b/src/Web/WebMVC/Controllers/CartController.cs @@ -1,89 +1,79 @@ -using Microsoft.AspNetCore.Authentication.OpenIdConnect; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.eShopOnContainers.WebMVC.Services; -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using System; -using System.Collections.Generic; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.WebMVC.Controllers; -namespace Microsoft.eShopOnContainers.WebMVC.Controllers +[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] +public class CartController : Controller { - [Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] - public class CartController : Controller + private readonly IBasketService _basketSvc; + private readonly ICatalogService _catalogSvc; + private readonly IIdentityParser _appUserParser; + + public CartController(IBasketService basketSvc, ICatalogService catalogSvc, IIdentityParser appUserParser) { - private readonly IBasketService _basketSvc; - private readonly ICatalogService _catalogSvc; - private readonly IIdentityParser _appUserParser; + _basketSvc = basketSvc; + _catalogSvc = catalogSvc; + _appUserParser = appUserParser; + } - public CartController(IBasketService basketSvc, ICatalogService catalogSvc, IIdentityParser appUserParser) + public async Task Index() + { + try { - _basketSvc = basketSvc; - _catalogSvc = catalogSvc; - _appUserParser = appUserParser; - } + var user = _appUserParser.Parse(HttpContext.User); + var vm = await _basketSvc.GetBasket(user); - public async Task Index() + return View(vm); + } + catch (Exception ex) { - try - { - var user = _appUserParser.Parse(HttpContext.User); - var vm = await _basketSvc.GetBasket(user); - - return View(vm); - } - catch (Exception ex) - { - HandleException(ex); - } - - return View(); + HandleException(ex); } + return View(); + } + - [HttpPost] - public async Task Index(Dictionary quantities, string action) + [HttpPost] + public async Task Index(Dictionary quantities, string action) + { + try { - try + var user = _appUserParser.Parse(HttpContext.User); + var basket = await _basketSvc.SetQuantities(user, quantities); + if (action == "[ Checkout ]") { - var user = _appUserParser.Parse(HttpContext.User); - var basket = await _basketSvc.SetQuantities(user, quantities); - if (action == "[ Checkout ]") - { - return RedirectToAction("Create", "Order"); - } + return RedirectToAction("Create", "Order"); } - catch (Exception ex) - { - HandleException(ex); - } - - return View(); + } + catch (Exception ex) + { + HandleException(ex); } - public async Task AddToCart(CatalogItem productDetails) + return View(); + } + + public async Task AddToCart(CatalogItem productDetails) + { + try { - try - { - if (productDetails?.Id != null) - { - var user = _appUserParser.Parse(HttpContext.User); - await _basketSvc.AddItemToBasket(user, productDetails.Id); - } - return RedirectToAction("Index", "Catalog"); - } - catch (Exception ex) + if (productDetails?.Id != null) { - // Catch error when Basket.api is in circuit-opened mode - HandleException(ex); + var user = _appUserParser.Parse(HttpContext.User); + await _basketSvc.AddItemToBasket(user, productDetails.Id); } - - return RedirectToAction("Index", "Catalog", new { errorMsg = ViewBag.BasketInoperativeMsg }); + return RedirectToAction("Index", "Catalog"); } - - private void HandleException(Exception ex) + catch (Exception ex) { - ViewBag.BasketInoperativeMsg = $"Basket Service is inoperative {ex.GetType().Name} - {ex.Message}"; + // Catch error when Basket.api is in circuit-opened mode + HandleException(ex); } + + return RedirectToAction("Index", "Catalog", new { errorMsg = ViewBag.BasketInoperativeMsg }); + } + + private void HandleException(Exception ex) + { + ViewBag.BasketInoperativeMsg = $"Basket Service is inoperative {ex.GetType().Name} - {ex.Message}"; } } diff --git a/src/Web/WebMVC/Controllers/CatalogController.cs b/src/Web/WebMVC/Controllers/CatalogController.cs index 16e2d417f..319d88219 100644 --- a/src/Web/WebMVC/Controllers/CatalogController.cs +++ b/src/Web/WebMVC/Controllers/CatalogController.cs @@ -1,45 +1,37 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.eShopOnContainers.WebMVC.Services; -using Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels; -using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination; -using System; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.WebMVC.Controllers; -namespace Microsoft.eShopOnContainers.WebMVC.Controllers +public class CatalogController : Controller { - public class CatalogController : Controller - { - private ICatalogService _catalogSvc; + private ICatalogService _catalogSvc; - public CatalogController(ICatalogService catalogSvc) => - _catalogSvc = catalogSvc; + public CatalogController(ICatalogService catalogSvc) => + _catalogSvc = catalogSvc; - public async Task Index(int? BrandFilterApplied, int? TypesFilterApplied, int? page, [FromQuery] string errorMsg) + public async Task Index(int? BrandFilterApplied, int? TypesFilterApplied, int? page, [FromQuery] string errorMsg) + { + var itemsPage = 9; + var catalog = await _catalogSvc.GetCatalogItems(page ?? 0, itemsPage, BrandFilterApplied, TypesFilterApplied); + var vm = new IndexViewModel() { - var itemsPage = 9; - var catalog = await _catalogSvc.GetCatalogItems(page ?? 0, itemsPage, BrandFilterApplied, TypesFilterApplied); - var vm = new IndexViewModel() + CatalogItems = catalog.Data, + Brands = await _catalogSvc.GetBrands(), + Types = await _catalogSvc.GetTypes(), + BrandFilterApplied = BrandFilterApplied ?? 0, + TypesFilterApplied = TypesFilterApplied ?? 0, + PaginationInfo = new PaginationInfo() { - CatalogItems = catalog.Data, - Brands = await _catalogSvc.GetBrands(), - Types = await _catalogSvc.GetTypes(), - BrandFilterApplied = BrandFilterApplied ?? 0, - TypesFilterApplied = TypesFilterApplied ?? 0, - PaginationInfo = new PaginationInfo() - { - ActualPage = page ?? 0, - ItemsPerPage = catalog.Data.Count, - TotalItems = catalog.Count, - TotalPages = (int)Math.Ceiling(((decimal)catalog.Count / itemsPage)) - } - }; + ActualPage = page ?? 0, + ItemsPerPage = catalog.Data.Count, + TotalItems = catalog.Count, + TotalPages = (int)Math.Ceiling(((decimal)catalog.Count / itemsPage)) + } + }; - vm.PaginationInfo.Next = (vm.PaginationInfo.ActualPage == vm.PaginationInfo.TotalPages - 1) ? "is-disabled" : ""; - vm.PaginationInfo.Previous = (vm.PaginationInfo.ActualPage == 0) ? "is-disabled" : ""; + vm.PaginationInfo.Next = (vm.PaginationInfo.ActualPage == vm.PaginationInfo.TotalPages - 1) ? "is-disabled" : ""; + vm.PaginationInfo.Previous = (vm.PaginationInfo.ActualPage == 0) ? "is-disabled" : ""; - ViewBag.BasketInoperativeMsg = errorMsg; + ViewBag.BasketInoperativeMsg = errorMsg; - return View(vm); - } + return View(vm); } } \ No newline at end of file diff --git a/src/Web/WebMVC/Controllers/ErrorController.cs b/src/Web/WebMVC/Controllers/ErrorController.cs index 222c7be51..0ce36eb6f 100644 --- a/src/Web/WebMVC/Controllers/ErrorController.cs +++ b/src/Web/WebMVC/Controllers/ErrorController.cs @@ -1,9 +1,6 @@ -using Microsoft.AspNetCore.Mvc; +namespace WebMVC.Controllers; -namespace WebMVC.Controllers +public class ErrorController : Controller { - public class ErrorController : Controller - { - public IActionResult Error() => View(); - } + public IActionResult Error() => View(); } diff --git a/src/Web/WebMVC/Controllers/OrderController.cs b/src/Web/WebMVC/Controllers/OrderController.cs index d5e98552a..a80d54072 100644 --- a/src/Web/WebMVC/Controllers/OrderController.cs +++ b/src/Web/WebMVC/Controllers/OrderController.cs @@ -1,82 +1,75 @@ -using Microsoft.AspNetCore.Authentication.OpenIdConnect; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.eShopOnContainers.WebMVC.Services; +namespace Microsoft.eShopOnContainers.WebMVC.Controllers; + using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using System; -using System.Threading.Tasks; -namespace Microsoft.eShopOnContainers.WebMVC.Controllers +[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] +public class OrderController : Controller { - [Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] - public class OrderController : Controller + private IOrderingService _orderSvc; + private IBasketService _basketSvc; + private readonly IIdentityParser _appUserParser; + public OrderController(IOrderingService orderSvc, IBasketService basketSvc, IIdentityParser appUserParser) { - private IOrderingService _orderSvc; - private IBasketService _basketSvc; - private readonly IIdentityParser _appUserParser; - public OrderController(IOrderingService orderSvc, IBasketService basketSvc, IIdentityParser appUserParser) - { - _appUserParser = appUserParser; - _orderSvc = orderSvc; - _basketSvc = basketSvc; - } + _appUserParser = appUserParser; + _orderSvc = orderSvc; + _basketSvc = basketSvc; + } - public async Task Create() - { + public async Task Create() + { - var user = _appUserParser.Parse(HttpContext.User); - var order = await _basketSvc.GetOrderDraft(user.Id); - var vm = _orderSvc.MapUserInfoIntoOrder(user, order); - vm.CardExpirationShortFormat(); + var user = _appUserParser.Parse(HttpContext.User); + var order = await _basketSvc.GetOrderDraft(user.Id); + var vm = _orderSvc.MapUserInfoIntoOrder(user, order); + vm.CardExpirationShortFormat(); - return View(vm); - } + return View(vm); + } - [HttpPost] - public async Task Checkout(Order model) + [HttpPost] + public async Task Checkout(Order model) + { + try { - try + if (ModelState.IsValid) { - if (ModelState.IsValid) - { - var user = _appUserParser.Parse(HttpContext.User); - var basket = _orderSvc.MapOrderToBasket(model); + var user = _appUserParser.Parse(HttpContext.User); + var basket = _orderSvc.MapOrderToBasket(model); - await _basketSvc.Checkout(basket); + await _basketSvc.Checkout(basket); - //Redirect to historic list. - return RedirectToAction("Index"); - } - } - catch (Exception ex) - { - ModelState.AddModelError("Error", $"It was not possible to create a new order, please try later on ({ex.GetType().Name} - {ex.Message})"); + //Redirect to historic list. + return RedirectToAction("Index"); } - - return View("Create", model); } - - public async Task Cancel(string orderId) + catch (Exception ex) { - await _orderSvc.CancelOrder(orderId); - - //Redirect to historic list. - return RedirectToAction("Index"); + ModelState.AddModelError("Error", $"It was not possible to create a new order, please try later on ({ex.GetType().Name} - {ex.Message})"); } - public async Task Detail(string orderId) - { - var user = _appUserParser.Parse(HttpContext.User); + return View("Create", model); + } - var order = await _orderSvc.GetOrder(user, orderId); - return View(order); - } + public async Task Cancel(string orderId) + { + await _orderSvc.CancelOrder(orderId); - public async Task Index(Order item) - { - var user = _appUserParser.Parse(HttpContext.User); - var vm = await _orderSvc.GetMyOrders(user); - return View(vm); - } + //Redirect to historic list. + return RedirectToAction("Index"); + } + + public async Task Detail(string orderId) + { + var user = _appUserParser.Parse(HttpContext.User); + + var order = await _orderSvc.GetOrder(user, orderId); + return View(order); + } + + public async Task Index(Order item) + { + var user = _appUserParser.Parse(HttpContext.User); + var vm = await _orderSvc.GetMyOrders(user); + return View(vm); } -} \ No newline at end of file +} diff --git a/src/Web/WebMVC/Controllers/OrderManagementController.cs b/src/Web/WebMVC/Controllers/OrderManagementController.cs index 27ad642ba..ac699bade 100644 --- a/src/Web/WebMVC/Controllers/OrderManagementController.cs +++ b/src/Web/WebMVC/Controllers/OrderManagementController.cs @@ -1,41 +1,32 @@ -using Microsoft.AspNetCore.Authentication.OpenIdConnect; -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.eShopOnContainers.WebMVC.Services; -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using System.Threading.Tasks; -using WebMVC.Services.ModelDTOs; +namespace WebMVC.Controllers; -namespace WebMVC.Controllers +[Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] +public class OrderManagementController : Controller { - [Authorize(AuthenticationSchemes = OpenIdConnectDefaults.AuthenticationScheme)] - public class OrderManagementController : Controller + private IOrderingService _orderSvc; + private readonly IIdentityParser _appUserParser; + public OrderManagementController(IOrderingService orderSvc, IIdentityParser appUserParser) { - private IOrderingService _orderSvc; - private readonly IIdentityParser _appUserParser; - public OrderManagementController(IOrderingService orderSvc, IIdentityParser appUserParser) - { - _appUserParser = appUserParser; - _orderSvc = orderSvc; - } + _appUserParser = appUserParser; + _orderSvc = orderSvc; + } - public async Task Index() - { - var user = _appUserParser.Parse(HttpContext.User); - var vm = await _orderSvc.GetMyOrders(user); + public async Task Index() + { + var user = _appUserParser.Parse(HttpContext.User); + var vm = await _orderSvc.GetMyOrders(user); - return View(vm); - } + return View(vm); + } - [HttpPost] - public async Task OrderProcess(string orderId, string actionCode) + [HttpPost] + public async Task OrderProcess(string orderId, string actionCode) + { + if (OrderProcessAction.Ship.Code == actionCode) { - if (OrderProcessAction.Ship.Code == actionCode) - { - await _orderSvc.ShipOrder(orderId); - } - - return RedirectToAction("Index"); + await _orderSvc.ShipOrder(orderId); } + + return RedirectToAction("Index"); } } diff --git a/src/Web/WebMVC/Controllers/TestController.cs b/src/Web/WebMVC/Controllers/TestController.cs index 6a90227c8..3054038ee 100644 --- a/src/Web/WebMVC/Controllers/TestController.cs +++ b/src/Web/WebMVC/Controllers/TestController.cs @@ -1,61 +1,52 @@ -using Microsoft.AspNetCore.Authorization; -using Microsoft.AspNetCore.Mvc; -using Microsoft.eShopOnContainers.WebMVC.Services; -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using System.Net.Http; -using System.Threading.Tasks; -using System.Text.Json; - -namespace WebMVC.Controllers +namespace WebMVC.Controllers; + +class TestPayload { - class TestPayload - { - public int CatalogItemId { get; set; } + public int CatalogItemId { get; set; } - public string BasketId { get; set; } + public string BasketId { get; set; } - public int Quantity { get; set; } - } + public int Quantity { get; set; } +} - [Authorize] - public class TestController : Controller +[Authorize] +public class TestController : Controller +{ + private readonly IHttpClientFactory _client; + private readonly IIdentityParser _appUserParser; + + public TestController(IHttpClientFactory client, IIdentityParser identityParser) { - private readonly IHttpClientFactory _client; - private readonly IIdentityParser _appUserParser; + _client = client; + _appUserParser = identityParser; + } - public TestController(IHttpClientFactory client, IIdentityParser identityParser) - { - _client = client; - _appUserParser = identityParser; - } + public async Task Ocelot() + { + var url = "http://apigw/shopping/api/v1/basket/items"; - public async Task Ocelot() + var payload = new TestPayload() { - var url = "http://apigw/shopping/api/v1/basket/items"; - - var payload = new TestPayload() - { - CatalogItemId = 1, - Quantity = 1, - BasketId = _appUserParser.Parse(User).Id - }; + CatalogItemId = 1, + Quantity = 1, + BasketId = _appUserParser.Parse(User).Id + }; - var content = new StringContent(JsonSerializer.Serialize(payload), System.Text.Encoding.UTF8, "application/json"); + var content = new StringContent(JsonSerializer.Serialize(payload), System.Text.Encoding.UTF8, "application/json"); - var response = await _client.CreateClient(nameof(IBasketService)) - .PostAsync(url, content); + var response = await _client.CreateClient(nameof(IBasketService)) + .PostAsync(url, content); - if (response.IsSuccessStatusCode) - { - var str = await response.Content.ReadAsStringAsync(); + if (response.IsSuccessStatusCode) + { + var str = await response.Content.ReadAsStringAsync(); - return Ok(str); - } - else - { - return Ok(new { response.StatusCode, response.ReasonPhrase }); - } + return Ok(str); + } + else + { + return Ok(new { response.StatusCode, response.ReasonPhrase }); } } } diff --git a/src/Web/WebMVC/Extensions/HttpClientExtensions.cs b/src/Web/WebMVC/Extensions/HttpClientExtensions.cs index 087c0dd8a..d1b11c9f7 100644 --- a/src/Web/WebMVC/Extensions/HttpClientExtensions.cs +++ b/src/Web/WebMVC/Extensions/HttpClientExtensions.cs @@ -1,35 +1,28 @@ -using System; -using System.IdentityModel.Tokens.Jwt; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Text; +namespace Microsoft.eShopOnContainers.WebMVC.Extensions; -namespace Microsoft.eShopOnContainers.WebMVC.Extensions +public static class HttpClientExtensions { - public static class HttpClientExtensions - { - public static void SetBasicAuthentication(this HttpClient client, string userName, string password) => - client.DefaultRequestHeaders.Authorization = new BasicAuthenticationHeaderValue(userName, password); + public static void SetBasicAuthentication(this HttpClient client, string userName, string password) => + client.DefaultRequestHeaders.Authorization = new BasicAuthenticationHeaderValue(userName, password); - public static void SetToken(this HttpClient client, string scheme, string token) => - client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(scheme, token); + public static void SetToken(this HttpClient client, string scheme, string token) => + client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(scheme, token); - public static void SetBearerToken(this HttpClient client, string token) => - client.SetToken(JwtConstants.TokenType, token); - } + public static void SetBearerToken(this HttpClient client, string token) => + client.SetToken(JwtConstants.TokenType, token); +} - public class BasicAuthenticationHeaderValue : AuthenticationHeaderValue - { - public BasicAuthenticationHeaderValue(string userName, string password) - : base("Basic", EncodeCredential(userName, password)) - { } +public class BasicAuthenticationHeaderValue : AuthenticationHeaderValue +{ + public BasicAuthenticationHeaderValue(string userName, string password) + : base("Basic", EncodeCredential(userName, password)) + { } - private static string EncodeCredential(string userName, string password) - { - Encoding encoding = Encoding.GetEncoding("iso-8859-1"); - string credential = String.Format("{0}:{1}", userName, password); + private static string EncodeCredential(string userName, string password) + { + Encoding encoding = Encoding.GetEncoding("iso-8859-1"); + string credential = String.Format("{0}:{1}", userName, password); - return Convert.ToBase64String(encoding.GetBytes(credential)); - } + return Convert.ToBase64String(encoding.GetBytes(credential)); } } diff --git a/src/Web/WebMVC/Extensions/SessionExtensions.cs b/src/Web/WebMVC/Extensions/SessionExtensions.cs index 29954bd8f..8175c26c4 100644 --- a/src/Web/WebMVC/Extensions/SessionExtensions.cs +++ b/src/Web/WebMVC/Extensions/SessionExtensions.cs @@ -1,8 +1,4 @@ -using Microsoft.AspNetCore.Http; -using System.Text.Json; - - -public static class SessionExtensions +public static class SessionExtensions { public static void SetObject(this ISession session, string key, object value) => session.SetString(key,JsonSerializer.Serialize(value)); diff --git a/src/Web/WebMVC/Infrastructure/API.cs b/src/Web/WebMVC/Infrastructure/API.cs index 0faeeb886..6e5ca68a2 100644 --- a/src/Web/WebMVC/Infrastructure/API.cs +++ b/src/Web/WebMVC/Infrastructure/API.cs @@ -1,86 +1,85 @@ -namespace WebMVC.Infrastructure +namespace WebMVC.Infrastructure; + +public static class API { - public static class API + + public static class Purchase + { + public static string AddItemToBasket(string baseUri) => $"{baseUri}/basket/items"; + public static string UpdateBasketItem(string baseUri) => $"{baseUri}/basket/items"; + + public static string GetOrderDraft(string baseUri, string basketId) => $"{baseUri}/order/draft/{basketId}"; + } + + public static class Basket { + public static string GetBasket(string baseUri, string basketId) => $"{baseUri}/{basketId}"; + public static string UpdateBasket(string baseUri) => baseUri; + public static string CheckoutBasket(string baseUri) => $"{baseUri}/checkout"; + public static string CleanBasket(string baseUri, string basketId) => $"{baseUri}/{basketId}"; + } - public static class Purchase + public static class Order + { + public static string GetOrder(string baseUri, string orderId) { - public static string AddItemToBasket(string baseUri) => $"{baseUri}/basket/items"; - public static string UpdateBasketItem(string baseUri) => $"{baseUri}/basket/items"; + return $"{baseUri}/{orderId}"; + } - public static string GetOrderDraft(string baseUri, string basketId) => $"{baseUri}/order/draft/{basketId}"; + public static string GetAllMyOrders(string baseUri) + { + return baseUri; } - public static class Basket + public static string AddNewOrder(string baseUri) { - public static string GetBasket(string baseUri, string basketId) => $"{baseUri}/{basketId}"; - public static string UpdateBasket(string baseUri) => baseUri; - public static string CheckoutBasket(string baseUri) => $"{baseUri}/checkout"; - public static string CleanBasket(string baseUri, string basketId) => $"{baseUri}/{basketId}"; + return $"{baseUri}/new"; } - public static class Order + public static string CancelOrder(string baseUri) { - public static string GetOrder(string baseUri, string orderId) - { - return $"{baseUri}/{orderId}"; - } + return $"{baseUri}/cancel"; + } - public static string GetAllMyOrders(string baseUri) - { - return baseUri; - } + public static string ShipOrder(string baseUri) + { + return $"{baseUri}/ship"; + } + } - public static string AddNewOrder(string baseUri) + public static class Catalog + { + public static string GetAllCatalogItems(string baseUri, int page, int take, int? brand, int? type) + { + var filterQs = ""; + + if (type.HasValue) { - return $"{baseUri}/new"; - } + var brandQs = (brand.HasValue) ? brand.Value.ToString() : string.Empty; + filterQs = $"/type/{type.Value}/brand/{brandQs}"; - public static string CancelOrder(string baseUri) + } + else if (brand.HasValue) { - return $"{baseUri}/cancel"; + var brandQs = (brand.HasValue) ? brand.Value.ToString() : string.Empty; + filterQs = $"/type/all/brand/{brandQs}"; } - - public static string ShipOrder(string baseUri) + else { - return $"{baseUri}/ship"; + filterQs = string.Empty; } + + return $"{baseUri}items{filterQs}?pageIndex={page}&pageSize={take}"; } - public static class Catalog + public static string GetAllBrands(string baseUri) { - public static string GetAllCatalogItems(string baseUri, int page, int take, int? brand, int? type) - { - var filterQs = ""; - - if (type.HasValue) - { - var brandQs = (brand.HasValue) ? brand.Value.ToString() : string.Empty; - filterQs = $"/type/{type.Value}/brand/{brandQs}"; - - } - else if (brand.HasValue) - { - var brandQs = (brand.HasValue) ? brand.Value.ToString() : string.Empty; - filterQs = $"/type/all/brand/{brandQs}"; - } - else - { - filterQs = string.Empty; - } - - return $"{baseUri}items{filterQs}?pageIndex={page}&pageSize={take}"; - } - - public static string GetAllBrands(string baseUri) - { - return $"{baseUri}catalogBrands"; - } + return $"{baseUri}catalogBrands"; + } - public static string GetAllTypes(string baseUri) - { - return $"{baseUri}catalogTypes"; - } + public static string GetAllTypes(string baseUri) + { + return $"{baseUri}catalogTypes"; } } -} \ No newline at end of file +} diff --git a/src/Web/WebMVC/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs b/src/Web/WebMVC/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs index 1b2446197..e9f21a4f0 100644 --- a/src/Web/WebMVC/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs +++ b/src/Web/WebMVC/Infrastructure/HttpClientAuthorizationDelegatingHandler.cs @@ -1,49 +1,40 @@ -using Microsoft.AspNetCore.Authentication; -using Microsoft.AspNetCore.Http; -using System.Collections.Generic; -using System.Net.Http; -using System.Net.Http.Headers; -using System.Threading; -using System.Threading.Tasks; - -namespace WebMVC.Infrastructure +namespace WebMVC.Infrastructure; + +public class HttpClientAuthorizationDelegatingHandler + : DelegatingHandler { - public class HttpClientAuthorizationDelegatingHandler - : DelegatingHandler + private readonly IHttpContextAccessor _httpContextAccessor; + + public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor httpContextAccessor) { - private readonly IHttpContextAccessor _httpContextAccessor; + _httpContextAccessor = httpContextAccessor; + } - public HttpClientAuthorizationDelegatingHandler(IHttpContextAccessor httpContextAccessor) - { - _httpContextAccessor = httpContextAccessor; - } + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + var authorizationHeader = _httpContextAccessor.HttpContext + .Request.Headers["Authorization"]; - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + if (!string.IsNullOrEmpty(authorizationHeader)) { - var authorizationHeader = _httpContextAccessor.HttpContext - .Request.Headers["Authorization"]; - - if (!string.IsNullOrEmpty(authorizationHeader)) - { - request.Headers.Add("Authorization", new List() { authorizationHeader }); - } - - var token = await GetToken(); + request.Headers.Add("Authorization", new List() { authorizationHeader }); + } - if (token != null) - { - request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); - } + var token = await GetToken(); - return await base.SendAsync(request, cancellationToken); + if (token != null) + { + request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token); } - async Task GetToken() - { - const string ACCESS_TOKEN = "access_token"; + return await base.SendAsync(request, cancellationToken); + } - return await _httpContextAccessor.HttpContext - .GetTokenAsync(ACCESS_TOKEN); - } + async Task GetToken() + { + const string ACCESS_TOKEN = "access_token"; + + return await _httpContextAccessor.HttpContext + .GetTokenAsync(ACCESS_TOKEN); } } diff --git a/src/Web/WebMVC/Infrastructure/HttpClientRequestIdDelegatingHandler.cs b/src/Web/WebMVC/Infrastructure/HttpClientRequestIdDelegatingHandler.cs index a59c757c0..798a9a034 100644 --- a/src/Web/WebMVC/Infrastructure/HttpClientRequestIdDelegatingHandler.cs +++ b/src/Web/WebMVC/Infrastructure/HttpClientRequestIdDelegatingHandler.cs @@ -1,29 +1,23 @@ -using System; -using System.Net.Http; -using System.Threading; -using System.Threading.Tasks; +namespace WebMVC.Infrastructure; -namespace WebMVC.Infrastructure +public class HttpClientRequestIdDelegatingHandler + : DelegatingHandler { - public class HttpClientRequestIdDelegatingHandler - : DelegatingHandler - { - public HttpClientRequestIdDelegatingHandler() - { - } + public HttpClientRequestIdDelegatingHandler() + { + } - protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + protected override async Task SendAsync(HttpRequestMessage request, CancellationToken cancellationToken) + { + if (request.Method == HttpMethod.Post || request.Method == HttpMethod.Put) { - if (request.Method == HttpMethod.Post || request.Method == HttpMethod.Put) + if (!request.Headers.Contains("x-requestid")) { - if (!request.Headers.Contains("x-requestid")) - { - request.Headers.Add("x-requestid", Guid.NewGuid().ToString()); - } + request.Headers.Add("x-requestid", Guid.NewGuid().ToString()); } - - return await base.SendAsync(request, cancellationToken); } + + return await base.SendAsync(request, cancellationToken); } -} +} \ No newline at end of file diff --git a/src/Web/WebMVC/Infrastructure/WebContextSeed.cs b/src/Web/WebMVC/Infrastructure/WebContextSeed.cs index 8b7a749e0..a0ab5832e 100644 --- a/src/Web/WebMVC/Infrastructure/WebContextSeed.cs +++ b/src/Web/WebMVC/Infrastructure/WebContextSeed.cs @@ -1,97 +1,85 @@ -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Hosting; -using Microsoft.eShopOnContainers.WebMVC; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; +namespace WebMVC.Infrastructure; using Serilog; -using System; -using System.IO; -using System.IO.Compression; -using System.Linq; -namespace WebMVC.Infrastructure +public class WebContextSeed { - public class WebContextSeed + public static void Seed(IApplicationBuilder applicationBuilder, IWebHostEnvironment env) { - public static void Seed(IApplicationBuilder applicationBuilder, IWebHostEnvironment env) - { - var log = Serilog.Log.Logger; + var log = Serilog.Log.Logger; - var settings = (AppSettings)applicationBuilder - .ApplicationServices.GetRequiredService>().Value; + var settings = (AppSettings)applicationBuilder + .ApplicationServices.GetRequiredService>().Value; - var useCustomizationData = settings.UseCustomizationData; - var contentRootPath = env.ContentRootPath; - var webroot = env.WebRootPath; + var useCustomizationData = settings.UseCustomizationData; + var contentRootPath = env.ContentRootPath; + var webroot = env.WebRootPath; - if (useCustomizationData) - { - GetPreconfiguredImages(contentRootPath, webroot, log); + if (useCustomizationData) + { + GetPreconfiguredImages(contentRootPath, webroot, log); - GetPreconfiguredCSS(contentRootPath, webroot, log); - } + GetPreconfiguredCSS(contentRootPath, webroot, log); } + } - static void GetPreconfiguredCSS(string contentRootPath, string webroot, Serilog.ILogger log) + static void GetPreconfiguredCSS(string contentRootPath, string webroot, ILogger log) + { + try { - try + string overrideCssFile = Path.Combine(contentRootPath, "Setup", "override.css"); + if (!File.Exists(overrideCssFile)) { - string overrideCssFile = Path.Combine(contentRootPath, "Setup", "override.css"); - if (!File.Exists(overrideCssFile)) - { - log.Error("Override css file '{FileName}' does not exists.", overrideCssFile); - return; - } - - string destinationFilename = Path.Combine(webroot, "css", "override.css"); - File.Copy(overrideCssFile, destinationFilename, true); - } - catch (Exception ex) - { - log.Error(ex, "EXCEPTION ERROR: {Message}", ex.Message); + log.Error("Override css file '{FileName}' does not exists.", overrideCssFile); + return; } + + string destinationFilename = Path.Combine(webroot, "css", "override.css"); + File.Copy(overrideCssFile, destinationFilename, true); } + catch (Exception ex) + { + log.Error(ex, "EXCEPTION ERROR: {Message}", ex.Message); + } + } - static void GetPreconfiguredImages(string contentRootPath, string webroot, Serilog.ILogger log) + static void GetPreconfiguredImages(string contentRootPath, string webroot, ILogger log) + { + try { - try + string imagesZipFile = Path.Combine(contentRootPath, "Setup", "images.zip"); + if (!File.Exists(imagesZipFile)) { - string imagesZipFile = Path.Combine(contentRootPath, "Setup", "images.zip"); - if (!File.Exists(imagesZipFile)) - { - log.Error("Zip file '{ZipFileName}' does not exists.", imagesZipFile); - return; - } + log.Error("Zip file '{ZipFileName}' does not exists.", imagesZipFile); + return; + } - string imagePath = Path.Combine(webroot, "images"); - string[] imageFiles = Directory.GetFiles(imagePath).Select(file => Path.GetFileName(file)).ToArray(); + string imagePath = Path.Combine(webroot, "images"); + string[] imageFiles = Directory.GetFiles(imagePath).Select(file => Path.GetFileName(file)).ToArray(); - using (ZipArchive zip = ZipFile.Open(imagesZipFile, ZipArchiveMode.Read)) + using (ZipArchive zip = ZipFile.Open(imagesZipFile, ZipArchiveMode.Read)) + { + foreach (ZipArchiveEntry entry in zip.Entries) { - foreach (ZipArchiveEntry entry in zip.Entries) + if (imageFiles.Contains(entry.Name)) { - if (imageFiles.Contains(entry.Name)) - { - string destinationFilename = Path.Combine(imagePath, entry.Name); - if (File.Exists(destinationFilename)) - { - File.Delete(destinationFilename); - } - entry.ExtractToFile(destinationFilename); - } - else + string destinationFilename = Path.Combine(imagePath, entry.Name); + if (File.Exists(destinationFilename)) { - log.Warning("Skipped file '{FileName}' in zipfile '{ZipFileName}'", entry.Name, imagesZipFile); + File.Delete(destinationFilename); } + entry.ExtractToFile(destinationFilename); + } + else + { + log.Warning("Skipped file '{FileName}' in zipfile '{ZipFileName}'", entry.Name, imagesZipFile); } } } - catch (Exception ex) - { - log.Error(ex, "EXCEPTION ERROR: {Message}", ex.Message); - } } - + catch (Exception ex) + { + log.Error(ex, "EXCEPTION ERROR: {Message}", ex.Message); + } } -} +} \ No newline at end of file diff --git a/src/Web/WebMVC/Program.cs b/src/Web/WebMVC/Program.cs index a95578718..cf02fb5b3 100644 --- a/src/Web/WebMVC/Program.cs +++ b/src/Web/WebMVC/Program.cs @@ -1,13 +1,4 @@ -using Microsoft.AspNetCore; -using Microsoft.AspNetCore.Hosting; -using Microsoft.eShopOnContainers.WebMVC; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.Logging; -using Serilog; -using System; -using System.IO; - -var configuration = GetConfiguration(); +var configuration = GetConfiguration(); Log.Logger = CreateSerilogLogger(configuration); diff --git a/src/Web/WebMVC/Services/BasketService.cs b/src/Web/WebMVC/Services/BasketService.cs index 8a0be9e71..eeadf37b7 100644 --- a/src/Web/WebMVC/Services/BasketService.cs +++ b/src/Web/WebMVC/Services/BasketService.cs @@ -1,130 +1,120 @@ -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Threading.Tasks; -using WebMVC.Infrastructure; -using WebMVC.Services.ModelDTOs; -using System.Text.Json; - -namespace Microsoft.eShopOnContainers.WebMVC.Services +namespace Microsoft.eShopOnContainers.WebMVC.Services; + +using Microsoft.eShopOnContainers.WebMVC.ViewModels; + +public class BasketService : IBasketService { - public class BasketService : IBasketService + private readonly IOptions _settings; + private readonly HttpClient _apiClient; + private readonly ILogger _logger; + private readonly string _basketByPassUrl; + private readonly string _purchaseUrl; + + public BasketService(HttpClient httpClient, IOptions settings, ILogger logger) { - private readonly IOptions _settings; - private readonly HttpClient _apiClient; - private readonly ILogger _logger; - private readonly string _basketByPassUrl; - private readonly string _purchaseUrl; + _apiClient = httpClient; + _settings = settings; + _logger = logger; - public BasketService(HttpClient httpClient, IOptions settings, ILogger logger) - { - _apiClient = httpClient; - _settings = settings; - _logger = logger; + _basketByPassUrl = $"{_settings.Value.PurchaseUrl}/b/api/v1/basket"; + _purchaseUrl = $"{_settings.Value.PurchaseUrl}/api/v1"; + } - _basketByPassUrl = $"{_settings.Value.PurchaseUrl}/b/api/v1/basket"; - _purchaseUrl = $"{_settings.Value.PurchaseUrl}/api/v1"; - } + public async Task GetBasket(ApplicationUser user) + { + var uri = API.Basket.GetBasket(_basketByPassUrl, user.Id); + _logger.LogDebug("[GetBasket] -> Calling {Uri} to get the basket", uri); + var response = await _apiClient.GetAsync(uri); + _logger.LogDebug("[GetBasket] -> response code {StatusCode}", response.StatusCode); + var responseString = await response.Content.ReadAsStringAsync(); + return string.IsNullOrEmpty(responseString) ? + new Basket() { BuyerId = user.Id } : + JsonSerializer.Deserialize(responseString, new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true + }); + } - public async Task GetBasket(ApplicationUser user) - { - var uri = API.Basket.GetBasket(_basketByPassUrl, user.Id); - _logger.LogDebug("[GetBasket] -> Calling {Uri} to get the basket", uri); - var response = await _apiClient.GetAsync(uri); - _logger.LogDebug("[GetBasket] -> response code {StatusCode}", response.StatusCode); - var responseString = await response.Content.ReadAsStringAsync(); - return string.IsNullOrEmpty(responseString) ? - new Basket() { BuyerId = user.Id } : - JsonSerializer.Deserialize(responseString, new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true - }); - } - - public async Task UpdateBasket(Basket basket) - { - var uri = API.Basket.UpdateBasket(_basketByPassUrl); + public async Task UpdateBasket(Basket basket) + { + var uri = API.Basket.UpdateBasket(_basketByPassUrl); - var basketContent = new StringContent(JsonSerializer.Serialize(basket), System.Text.Encoding.UTF8, "application/json"); + var basketContent = new StringContent(JsonSerializer.Serialize(basket), System.Text.Encoding.UTF8, "application/json"); - var response = await _apiClient.PostAsync(uri, basketContent); + var response = await _apiClient.PostAsync(uri, basketContent); - response.EnsureSuccessStatusCode(); + response.EnsureSuccessStatusCode(); - return basket; - } + return basket; + } - public async Task Checkout(BasketDTO basket) - { - var uri = API.Basket.CheckoutBasket(_basketByPassUrl); - var basketContent = new StringContent(JsonSerializer.Serialize(basket), System.Text.Encoding.UTF8, "application/json"); + public async Task Checkout(BasketDTO basket) + { + var uri = API.Basket.CheckoutBasket(_basketByPassUrl); + var basketContent = new StringContent(JsonSerializer.Serialize(basket), System.Text.Encoding.UTF8, "application/json"); - _logger.LogInformation("Uri chechout {uri}", uri); + _logger.LogInformation("Uri chechout {uri}", uri); - var response = await _apiClient.PostAsync(uri, basketContent); + var response = await _apiClient.PostAsync(uri, basketContent); - response.EnsureSuccessStatusCode(); - } + response.EnsureSuccessStatusCode(); + } - public async Task SetQuantities(ApplicationUser user, Dictionary quantities) - { - var uri = API.Purchase.UpdateBasketItem(_purchaseUrl); + public async Task SetQuantities(ApplicationUser user, Dictionary quantities) + { + var uri = API.Purchase.UpdateBasketItem(_purchaseUrl); - var basketUpdate = new + var basketUpdate = new + { + BasketId = user.Id, + Updates = quantities.Select(kvp => new { - BasketId = user.Id, - Updates = quantities.Select(kvp => new - { - BasketItemId = kvp.Key, - NewQty = kvp.Value - }).ToArray() - }; + BasketItemId = kvp.Key, + NewQty = kvp.Value + }).ToArray() + }; - var basketContent = new StringContent(JsonSerializer.Serialize(basketUpdate), System.Text.Encoding.UTF8, "application/json"); + var basketContent = new StringContent(JsonSerializer.Serialize(basketUpdate), System.Text.Encoding.UTF8, "application/json"); - var response = await _apiClient.PutAsync(uri, basketContent); + var response = await _apiClient.PutAsync(uri, basketContent); - response.EnsureSuccessStatusCode(); + response.EnsureSuccessStatusCode(); - var jsonResponse = await response.Content.ReadAsStringAsync(); + var jsonResponse = await response.Content.ReadAsStringAsync(); - return JsonSerializer.Deserialize(jsonResponse, new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true - }); - } - - public async Task GetOrderDraft(string basketId) + return JsonSerializer.Deserialize(jsonResponse, new JsonSerializerOptions { - var uri = API.Purchase.GetOrderDraft(_purchaseUrl, basketId); - - var responseString = await _apiClient.GetStringAsync(uri); + PropertyNameCaseInsensitive = true + }); + } - var response = JsonSerializer.Deserialize(responseString, new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true - }); + public async Task GetOrderDraft(string basketId) + { + var uri = API.Purchase.GetOrderDraft(_purchaseUrl, basketId); - return response; - } + var responseString = await _apiClient.GetStringAsync(uri); - public async Task AddItemToBasket(ApplicationUser user, int productId) + var response = JsonSerializer.Deserialize(responseString, new JsonSerializerOptions { - var uri = API.Purchase.AddItemToBasket(_purchaseUrl); + PropertyNameCaseInsensitive = true + }); - var newItem = new - { - CatalogItemId = productId, - BasketId = user.Id, - Quantity = 1 - }; + return response; + } + + public async Task AddItemToBasket(ApplicationUser user, int productId) + { + var uri = API.Purchase.AddItemToBasket(_purchaseUrl); + + var newItem = new + { + CatalogItemId = productId, + BasketId = user.Id, + Quantity = 1 + }; - var basketContent = new StringContent(JsonSerializer.Serialize(newItem), System.Text.Encoding.UTF8, "application/json"); + var basketContent = new StringContent(JsonSerializer.Serialize(newItem), System.Text.Encoding.UTF8, "application/json"); - var response = await _apiClient.PostAsync(uri, basketContent); - } + var response = await _apiClient.PostAsync(uri, basketContent); } } diff --git a/src/Web/WebMVC/Services/CatalogService.cs b/src/Web/WebMVC/Services/CatalogService.cs index e7806a738..96ad9c3c0 100644 --- a/src/Web/WebMVC/Services/CatalogService.cs +++ b/src/Web/WebMVC/Services/CatalogService.cs @@ -1,91 +1,80 @@ -using Microsoft.AspNetCore.Mvc.Rendering; -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading.Tasks; -using WebMVC.Infrastructure; -using System.Text.Json; - -namespace Microsoft.eShopOnContainers.WebMVC.Services +namespace Microsoft.eShopOnContainers.WebMVC.Services; + +public class CatalogService : ICatalogService { - public class CatalogService : ICatalogService - { - private readonly IOptions _settings; - private readonly HttpClient _httpClient; - private readonly ILogger _logger; + private readonly IOptions _settings; + private readonly HttpClient _httpClient; + private readonly ILogger _logger; - private readonly string _remoteServiceBaseUrl; + private readonly string _remoteServiceBaseUrl; - public CatalogService(HttpClient httpClient, ILogger logger, IOptions settings) - { - _httpClient = httpClient; - _settings = settings; - _logger = logger; + public CatalogService(HttpClient httpClient, ILogger logger, IOptions settings) + { + _httpClient = httpClient; + _settings = settings; + _logger = logger; - _remoteServiceBaseUrl = $"{_settings.Value.PurchaseUrl}/c/api/v1/catalog/"; - } + _remoteServiceBaseUrl = $"{_settings.Value.PurchaseUrl}/c/api/v1/catalog/"; + } - public async Task GetCatalogItems(int page, int take, int? brand, int? type) - { - var uri = API.Catalog.GetAllCatalogItems(_remoteServiceBaseUrl, page, take, brand, type); + public async Task GetCatalogItems(int page, int take, int? brand, int? type) + { + var uri = API.Catalog.GetAllCatalogItems(_remoteServiceBaseUrl, page, take, brand, type); - var responseString = await _httpClient.GetStringAsync(uri); + var responseString = await _httpClient.GetStringAsync(uri); - var catalog = JsonSerializer.Deserialize(responseString, new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true - }); + var catalog = JsonSerializer.Deserialize(responseString, new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true + }); - return catalog; - } + return catalog; + } - public async Task> GetBrands() - { - var uri = API.Catalog.GetAllBrands(_remoteServiceBaseUrl); + public async Task> GetBrands() + { + var uri = API.Catalog.GetAllBrands(_remoteServiceBaseUrl); - var responseString = await _httpClient.GetStringAsync(uri); + var responseString = await _httpClient.GetStringAsync(uri); - var items = new List(); + var items = new List(); - items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true }); + items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true }); - using var brands = JsonDocument.Parse(responseString); + using var brands = JsonDocument.Parse(responseString); - foreach (JsonElement brand in brands.RootElement.EnumerateArray()) + foreach (JsonElement brand in brands.RootElement.EnumerateArray()) + { + items.Add(new SelectListItem() { - items.Add(new SelectListItem() - { - Value = brand.GetProperty("id").ToString(), - Text = brand.GetProperty("brand").ToString() - }); - } - - return items; + Value = brand.GetProperty("id").ToString(), + Text = brand.GetProperty("brand").ToString() + }); } - public async Task> GetTypes() - { - var uri = API.Catalog.GetAllTypes(_remoteServiceBaseUrl); + return items; + } + + public async Task> GetTypes() + { + var uri = API.Catalog.GetAllTypes(_remoteServiceBaseUrl); - var responseString = await _httpClient.GetStringAsync(uri); + var responseString = await _httpClient.GetStringAsync(uri); - var items = new List(); - items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true }); + var items = new List(); + items.Add(new SelectListItem() { Value = null, Text = "All", Selected = true }); - using var catalogTypes = JsonDocument.Parse(responseString); + using var catalogTypes = JsonDocument.Parse(responseString); - foreach (JsonElement catalogType in catalogTypes.RootElement.EnumerateArray()) + foreach (JsonElement catalogType in catalogTypes.RootElement.EnumerateArray()) + { + items.Add(new SelectListItem() { - items.Add(new SelectListItem() - { - Value = catalogType.GetProperty("id").ToString(), - Text = catalogType.GetProperty("type").ToString() - }); - } - - return items; + Value = catalogType.GetProperty("id").ToString(), + Text = catalogType.GetProperty("type").ToString() + }); } + + return items; } } diff --git a/src/Web/WebMVC/Services/IBasketService.cs b/src/Web/WebMVC/Services/IBasketService.cs index cc576ec11..9ef09ac3a 100644 --- a/src/Web/WebMVC/Services/IBasketService.cs +++ b/src/Web/WebMVC/Services/IBasketService.cs @@ -1,17 +1,13 @@ -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using System.Collections.Generic; -using System.Threading.Tasks; -using WebMVC.Services.ModelDTOs; +namespace Microsoft.eShopOnContainers.WebMVC.Services; -namespace Microsoft.eShopOnContainers.WebMVC.Services +using Microsoft.eShopOnContainers.WebMVC.ViewModels; + +public interface IBasketService { - public interface IBasketService - { - Task GetBasket(ApplicationUser user); - Task AddItemToBasket(ApplicationUser user, int productId); - Task UpdateBasket(Basket basket); - Task Checkout(BasketDTO basket); - Task SetQuantities(ApplicationUser user, Dictionary quantities); - Task GetOrderDraft(string basketId); - } + Task GetBasket(ApplicationUser user); + Task AddItemToBasket(ApplicationUser user, int productId); + Task UpdateBasket(Basket basket); + Task Checkout(BasketDTO basket); + Task SetQuantities(ApplicationUser user, Dictionary quantities); + Task GetOrderDraft(string basketId); } diff --git a/src/Web/WebMVC/Services/ICatalogService.cs b/src/Web/WebMVC/Services/ICatalogService.cs index 3879ad13d..905ce9a18 100644 --- a/src/Web/WebMVC/Services/ICatalogService.cs +++ b/src/Web/WebMVC/Services/ICatalogService.cs @@ -1,14 +1,8 @@ -using Microsoft.AspNetCore.Mvc.Rendering; -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using System.Collections.Generic; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.WebMVC.Services; -namespace Microsoft.eShopOnContainers.WebMVC.Services +public interface ICatalogService { - public interface ICatalogService - { - Task GetCatalogItems(int page, int take, int? brand, int? type); - Task> GetBrands(); - Task> GetTypes(); - } + Task GetCatalogItems(int page, int take, int? brand, int? type); + Task> GetBrands(); + Task> GetTypes(); } diff --git a/src/Web/WebMVC/Services/IIdentityParser.cs b/src/Web/WebMVC/Services/IIdentityParser.cs index aaf2ab8cd..4625bb62f 100644 --- a/src/Web/WebMVC/Services/IIdentityParser.cs +++ b/src/Web/WebMVC/Services/IIdentityParser.cs @@ -1,9 +1,6 @@ -using System.Security.Principal; +namespace Microsoft.eShopOnContainers.WebMVC.Services; -namespace Microsoft.eShopOnContainers.WebMVC.Services +public interface IIdentityParser { - public interface IIdentityParser - { - T Parse(IPrincipal principal); - } + T Parse(IPrincipal principal); } diff --git a/src/Web/WebMVC/Services/IOrderingService.cs b/src/Web/WebMVC/Services/IOrderingService.cs index cc1968c53..2c34b7d01 100644 --- a/src/Web/WebMVC/Services/IOrderingService.cs +++ b/src/Web/WebMVC/Services/IOrderingService.cs @@ -1,18 +1,13 @@ -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using System.Collections.Generic; -using System.Threading.Tasks; -using WebMVC.Services.ModelDTOs; +namespace Microsoft.eShopOnContainers.WebMVC.Services; +using Microsoft.eShopOnContainers.WebMVC.ViewModels; -namespace Microsoft.eShopOnContainers.WebMVC.Services +public interface IOrderingService { - public interface IOrderingService - { - Task> GetMyOrders(ApplicationUser user); - Task GetOrder(ApplicationUser user, string orderId); - Task CancelOrder(string orderId); - Task ShipOrder(string orderId); - Order MapUserInfoIntoOrder(ApplicationUser user, Order order); - BasketDTO MapOrderToBasket(Order order); - void OverrideUserInfoIntoOrder(Order original, Order destination); - } + Task> GetMyOrders(ApplicationUser user); + Task GetOrder(ApplicationUser user, string orderId); + Task CancelOrder(string orderId); + Task ShipOrder(string orderId); + Order MapUserInfoIntoOrder(ApplicationUser user, Order order); + BasketDTO MapOrderToBasket(Order order); + void OverrideUserInfoIntoOrder(Order original, Order destination); } diff --git a/src/Web/WebMVC/Services/IdentityParser.cs b/src/Web/WebMVC/Services/IdentityParser.cs index 5360ebed4..bb969312d 100644 --- a/src/Web/WebMVC/Services/IdentityParser.cs +++ b/src/Web/WebMVC/Services/IdentityParser.cs @@ -1,42 +1,33 @@ -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using System; -using System.Linq; -using System.Security.Claims; -using System.Security.Principal; +namespace Microsoft.eShopOnContainers.WebMVC.Services; -namespace Microsoft.eShopOnContainers.WebMVC.Services +public class IdentityParser : IIdentityParser { - public class IdentityParser : IIdentityParser + public ApplicationUser Parse(IPrincipal principal) { - public ApplicationUser Parse(IPrincipal principal) + // Pattern matching 'is' expression + // assigns "claims" if "principal" is a "ClaimsPrincipal" + if (principal is ClaimsPrincipal claims) { - // Pattern matching 'is' expression - // assigns "claims" if "principal" is a "ClaimsPrincipal" - if (principal is ClaimsPrincipal claims) + return new ApplicationUser { - return new ApplicationUser - { - CardHolderName = claims.Claims.FirstOrDefault(x => x.Type == "card_holder")?.Value ?? "", - CardNumber = claims.Claims.FirstOrDefault(x => x.Type == "card_number")?.Value ?? "", - Expiration = claims.Claims.FirstOrDefault(x => x.Type == "card_expiration")?.Value ?? "", - CardType = int.Parse(claims.Claims.FirstOrDefault(x => x.Type == "missing")?.Value ?? "0"), - City = claims.Claims.FirstOrDefault(x => x.Type == "address_city")?.Value ?? "", - Country = claims.Claims.FirstOrDefault(x => x.Type == "address_country")?.Value ?? "", - Email = claims.Claims.FirstOrDefault(x => x.Type == "email")?.Value ?? "", - Id = claims.Claims.FirstOrDefault(x => x.Type == "sub")?.Value ?? "", - LastName = claims.Claims.FirstOrDefault(x => x.Type == "last_name")?.Value ?? "", - Name = claims.Claims.FirstOrDefault(x => x.Type == "name")?.Value ?? "", - PhoneNumber = claims.Claims.FirstOrDefault(x => x.Type == "phone_number")?.Value ?? "", - SecurityNumber = claims.Claims.FirstOrDefault(x => x.Type == "card_security_number")?.Value ?? "", - State = claims.Claims.FirstOrDefault(x => x.Type == "address_state")?.Value ?? "", - Street = claims.Claims.FirstOrDefault(x => x.Type == "address_street")?.Value ?? "", - ZipCode = claims.Claims.FirstOrDefault(x => x.Type == "address_zip_code")?.Value ?? "" - }; - } - throw new ArgumentException(message: "The principal must be a ClaimsPrincipal", paramName: nameof(principal)); + CardHolderName = claims.Claims.FirstOrDefault(x => x.Type == "card_holder")?.Value ?? "", + CardNumber = claims.Claims.FirstOrDefault(x => x.Type == "card_number")?.Value ?? "", + Expiration = claims.Claims.FirstOrDefault(x => x.Type == "card_expiration")?.Value ?? "", + CardType = int.Parse(claims.Claims.FirstOrDefault(x => x.Type == "missing")?.Value ?? "0"), + City = claims.Claims.FirstOrDefault(x => x.Type == "address_city")?.Value ?? "", + Country = claims.Claims.FirstOrDefault(x => x.Type == "address_country")?.Value ?? "", + Email = claims.Claims.FirstOrDefault(x => x.Type == "email")?.Value ?? "", + Id = claims.Claims.FirstOrDefault(x => x.Type == "sub")?.Value ?? "", + LastName = claims.Claims.FirstOrDefault(x => x.Type == "last_name")?.Value ?? "", + Name = claims.Claims.FirstOrDefault(x => x.Type == "name")?.Value ?? "", + PhoneNumber = claims.Claims.FirstOrDefault(x => x.Type == "phone_number")?.Value ?? "", + SecurityNumber = claims.Claims.FirstOrDefault(x => x.Type == "card_security_number")?.Value ?? "", + State = claims.Claims.FirstOrDefault(x => x.Type == "address_state")?.Value ?? "", + Street = claims.Claims.FirstOrDefault(x => x.Type == "address_street")?.Value ?? "", + ZipCode = claims.Claims.FirstOrDefault(x => x.Type == "address_zip_code")?.Value ?? "" + }; } + throw new ArgumentException(message: "The principal must be a ClaimsPrincipal", paramName: nameof(principal)); } } - - diff --git a/src/Web/WebMVC/Services/ModelDTOs/BasketDTO.cs b/src/Web/WebMVC/Services/ModelDTOs/BasketDTO.cs index 59b8ea2ca..c3d69656c 100644 --- a/src/Web/WebMVC/Services/ModelDTOs/BasketDTO.cs +++ b/src/Web/WebMVC/Services/ModelDTOs/BasketDTO.cs @@ -1,37 +1,32 @@ -using System; -using System.ComponentModel.DataAnnotations; +namespace WebMVC.Services.ModelDTOs; -namespace WebMVC.Services.ModelDTOs +public record BasketDTO { - public record BasketDTO - { - [Required] - public string City { get; init; } - [Required] - public string Street { get; init; } - [Required] - public string State { get; init; } - [Required] - public string Country { get; init; } + [Required] + public string City { get; init; } + [Required] + public string Street { get; init; } + [Required] + public string State { get; init; } + [Required] + public string Country { get; init; } - public string ZipCode { get; init; } - [Required] - public string CardNumber { get; init; } - [Required] - public string CardHolderName { get; init; } + public string ZipCode { get; init; } + [Required] + public string CardNumber { get; init; } + [Required] + public string CardHolderName { get; init; } - [Required] - public DateTime CardExpiration { get; init; } + [Required] + public DateTime CardExpiration { get; init; } - [Required] - public string CardSecurityNumber { get; init; } + [Required] + public string CardSecurityNumber { get; init; } - public int CardTypeId { get; init; } + public int CardTypeId { get; init; } - public string Buyer { get; init; } + public string Buyer { get; init; } - [Required] - public Guid RequestId { get; init; } - } + [Required] + public Guid RequestId { get; init; } } - diff --git a/src/Web/WebMVC/Services/ModelDTOs/LocationDTO.cs b/src/Web/WebMVC/Services/ModelDTOs/LocationDTO.cs index 626b2b2d3..2ac612284 100644 --- a/src/Web/WebMVC/Services/ModelDTOs/LocationDTO.cs +++ b/src/Web/WebMVC/Services/ModelDTOs/LocationDTO.cs @@ -1,8 +1,7 @@ -namespace WebMVC.Services.ModelDTOs +namespace WebMVC.Services.ModelDTOs; + +public record LocationDTO { - public record LocationDTO - { - public double Longitude { get; init; } - public double Latitude { get; init; } - } + public double Longitude { get; init; } + public double Latitude { get; init; } } diff --git a/src/Web/WebMVC/Services/ModelDTOs/OrderDTO.cs b/src/Web/WebMVC/Services/ModelDTOs/OrderDTO.cs index f88cf22f8..3a9de3c0f 100644 --- a/src/Web/WebMVC/Services/ModelDTOs/OrderDTO.cs +++ b/src/Web/WebMVC/Services/ModelDTOs/OrderDTO.cs @@ -1,10 +1,7 @@ -using System.ComponentModel.DataAnnotations; +namespace WebMVC.Services.ModelDTOs; -namespace WebMVC.Services.ModelDTOs +public record OrderDTO { - public record OrderDTO - { - [Required] - public string OrderNumber { get; init; } - } -} \ No newline at end of file + [Required] + public string OrderNumber { get; init; } +} diff --git a/src/Web/WebMVC/Services/ModelDTOs/OrderProcessAction.cs b/src/Web/WebMVC/Services/ModelDTOs/OrderProcessAction.cs index 34e4a2695..94d3f7939 100644 --- a/src/Web/WebMVC/Services/ModelDTOs/OrderProcessAction.cs +++ b/src/Web/WebMVC/Services/ModelDTOs/OrderProcessAction.cs @@ -1,20 +1,19 @@ -namespace WebMVC.Services.ModelDTOs +namespace WebMVC.Services.ModelDTOs; + +public record OrderProcessAction { - public record OrderProcessAction - { - public string Code { get; } - public string Name { get; } + public string Code { get; } + public string Name { get; } - public static OrderProcessAction Ship = new OrderProcessAction(nameof(Ship).ToLowerInvariant(), "Ship"); + public static OrderProcessAction Ship = new OrderProcessAction(nameof(Ship).ToLowerInvariant(), "Ship"); - protected OrderProcessAction() - { - } + protected OrderProcessAction() + { + } - public OrderProcessAction(string code, string name) - { - Code = code; - Name = name; - } + public OrderProcessAction(string code, string name) + { + Code = code; + Name = name; } } diff --git a/src/Web/WebMVC/Services/OrderingService.cs b/src/Web/WebMVC/Services/OrderingService.cs index 8699e61f8..f1422c51f 100644 --- a/src/Web/WebMVC/Services/OrderingService.cs +++ b/src/Web/WebMVC/Services/OrderingService.cs @@ -1,149 +1,140 @@ -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Net.Http; -using System.Threading.Tasks; -using WebMVC.Infrastructure; -using WebMVC.Services.ModelDTOs; -using System.Text.Json; - -namespace Microsoft.eShopOnContainers.WebMVC.Services -{ - public class OrderingService : IOrderingService - { - private HttpClient _httpClient; - private readonly string _remoteServiceBaseUrl; - private readonly IOptions _settings; +namespace Microsoft.eShopOnContainers.WebMVC.Services; +using Microsoft.eShopOnContainers.WebMVC.ViewModels; - public OrderingService(HttpClient httpClient, IOptions settings) - { - _httpClient = httpClient; - _settings = settings; +public class OrderingService : IOrderingService +{ + private HttpClient _httpClient; + private readonly string _remoteServiceBaseUrl; + private readonly IOptions _settings; - _remoteServiceBaseUrl = $"{settings.Value.PurchaseUrl}/o/api/v1/orders"; - } - async public Task GetOrder(ApplicationUser user, string id) - { - var uri = API.Order.GetOrder(_remoteServiceBaseUrl, id); + public OrderingService(HttpClient httpClient, IOptions settings) + { + _httpClient = httpClient; + _settings = settings; - var responseString = await _httpClient.GetStringAsync(uri); + _remoteServiceBaseUrl = $"{settings.Value.PurchaseUrl}/o/api/v1/orders"; + } - var response = JsonSerializer.Deserialize(responseString, new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true - }); + async public Task GetOrder(ApplicationUser user, string id) + { + var uri = API.Order.GetOrder(_remoteServiceBaseUrl, id); - return response; - } + var responseString = await _httpClient.GetStringAsync(uri); - async public Task> GetMyOrders(ApplicationUser user) + var response = JsonSerializer.Deserialize(responseString, new JsonSerializerOptions { - var uri = API.Order.GetAllMyOrders(_remoteServiceBaseUrl); + PropertyNameCaseInsensitive = true + }); - var responseString = await _httpClient.GetStringAsync(uri); + return response; + } - var response = JsonSerializer.Deserialize>(responseString, new JsonSerializerOptions - { - PropertyNameCaseInsensitive = true - }); + async public Task> GetMyOrders(ApplicationUser user) + { + var uri = API.Order.GetAllMyOrders(_remoteServiceBaseUrl); - return response; - } + var responseString = await _httpClient.GetStringAsync(uri); + var response = JsonSerializer.Deserialize>(responseString, new JsonSerializerOptions + { + PropertyNameCaseInsensitive = true + }); + return response; + } - async public Task CancelOrder(string orderId) - { - var order = new OrderDTO() - { - OrderNumber = orderId - }; - var uri = API.Order.CancelOrder(_remoteServiceBaseUrl); - var orderContent = new StringContent(JsonSerializer.Serialize(order), System.Text.Encoding.UTF8, "application/json"); - var response = await _httpClient.PutAsync(uri, orderContent); + async public Task CancelOrder(string orderId) + { + var order = new OrderDTO() + { + OrderNumber = orderId + }; - if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError) - { - throw new Exception("Error cancelling order, try later."); - } + var uri = API.Order.CancelOrder(_remoteServiceBaseUrl); + var orderContent = new StringContent(JsonSerializer.Serialize(order), System.Text.Encoding.UTF8, "application/json"); - response.EnsureSuccessStatusCode(); - } + var response = await _httpClient.PutAsync(uri, orderContent); - async public Task ShipOrder(string orderId) + if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError) { - var order = new OrderDTO() - { - OrderNumber = orderId - }; + throw new Exception("Error cancelling order, try later."); + } - var uri = API.Order.ShipOrder(_remoteServiceBaseUrl); - var orderContent = new StringContent(JsonSerializer.Serialize(order), System.Text.Encoding.UTF8, "application/json"); + response.EnsureSuccessStatusCode(); + } - var response = await _httpClient.PutAsync(uri, orderContent); + async public Task ShipOrder(string orderId) + { + var order = new OrderDTO() + { + OrderNumber = orderId + }; - if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError) - { - throw new Exception("Error in ship order process, try later."); - } + var uri = API.Order.ShipOrder(_remoteServiceBaseUrl); + var orderContent = new StringContent(JsonSerializer.Serialize(order), System.Text.Encoding.UTF8, "application/json"); - response.EnsureSuccessStatusCode(); - } + var response = await _httpClient.PutAsync(uri, orderContent); - public void OverrideUserInfoIntoOrder(Order original, Order destination) + if (response.StatusCode == System.Net.HttpStatusCode.InternalServerError) { - destination.City = original.City; - destination.Street = original.Street; - destination.State = original.State; - destination.Country = original.Country; - destination.ZipCode = original.ZipCode; - - destination.CardNumber = original.CardNumber; - destination.CardHolderName = original.CardHolderName; - destination.CardExpiration = original.CardExpiration; - destination.CardSecurityNumber = original.CardSecurityNumber; + throw new Exception("Error in ship order process, try later."); } - public Order MapUserInfoIntoOrder(ApplicationUser user, Order order) - { - order.City = user.City; - order.Street = user.Street; - order.State = user.State; - order.Country = user.Country; - order.ZipCode = user.ZipCode; - - order.CardNumber = user.CardNumber; - order.CardHolderName = user.CardHolderName; - order.CardExpiration = new DateTime(int.Parse("20" + user.Expiration.Split('/')[1]), int.Parse(user.Expiration.Split('/')[0]), 1); - order.CardSecurityNumber = user.SecurityNumber; - - return order; - } + response.EnsureSuccessStatusCode(); + } - public BasketDTO MapOrderToBasket(Order order) + public void OverrideUserInfoIntoOrder(Order original, Order destination) + { + destination.City = original.City; + destination.Street = original.Street; + destination.State = original.State; + destination.Country = original.Country; + destination.ZipCode = original.ZipCode; + + destination.CardNumber = original.CardNumber; + destination.CardHolderName = original.CardHolderName; + destination.CardExpiration = original.CardExpiration; + destination.CardSecurityNumber = original.CardSecurityNumber; + } + + public Order MapUserInfoIntoOrder(ApplicationUser user, Order order) + { + order.City = user.City; + order.Street = user.Street; + order.State = user.State; + order.Country = user.Country; + order.ZipCode = user.ZipCode; + + order.CardNumber = user.CardNumber; + order.CardHolderName = user.CardHolderName; + order.CardExpiration = new DateTime(int.Parse("20" + user.Expiration.Split('/')[1]), int.Parse(user.Expiration.Split('/')[0]), 1); + order.CardSecurityNumber = user.SecurityNumber; + + return order; + } + + public BasketDTO MapOrderToBasket(Order order) + { + order.CardExpirationApiFormat(); + + return new BasketDTO() { - order.CardExpirationApiFormat(); - - return new BasketDTO() - { - City = order.City, - Street = order.Street, - State = order.State, - Country = order.Country, - ZipCode = order.ZipCode, - CardNumber = order.CardNumber, - CardHolderName = order.CardHolderName, - CardExpiration = order.CardExpiration, - CardSecurityNumber = order.CardSecurityNumber, - CardTypeId = 1, - Buyer = order.Buyer, - RequestId = order.RequestId - }; - } + City = order.City, + Street = order.Street, + State = order.State, + Country = order.Country, + ZipCode = order.ZipCode, + CardNumber = order.CardNumber, + CardHolderName = order.CardHolderName, + CardExpiration = order.CardExpiration, + CardSecurityNumber = order.CardSecurityNumber, + CardTypeId = 1, + Buyer = order.Buyer, + RequestId = order.RequestId + }; } } diff --git a/src/Web/WebMVC/Startup.cs b/src/Web/WebMVC/Startup.cs index 427e234c7..405d2ced4 100644 --- a/src/Web/WebMVC/Startup.cs +++ b/src/Web/WebMVC/Startup.cs @@ -1,212 +1,190 @@ -using Devspaces.Support; -using HealthChecks.UI.Client; -using Microsoft.AspNetCore.Authentication.Cookies; -using Microsoft.AspNetCore.Authentication.JwtBearer; -using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.DataProtection; -using Microsoft.AspNetCore.Diagnostics.HealthChecks; -using Microsoft.AspNetCore.Hosting; -using Microsoft.AspNetCore.Http; -using Microsoft.eShopOnContainers.WebMVC.Services; -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Diagnostics.HealthChecks; -using Microsoft.Extensions.Hosting; -using Microsoft.IdentityModel.Logging; -using StackExchange.Redis; -using System; -using System.IdentityModel.Tokens.Jwt; -using WebMVC.Infrastructure; - -namespace Microsoft.eShopOnContainers.WebMVC +namespace Microsoft.eShopOnContainers.WebMVC; + +public class Startup { - public class Startup + public Startup(IConfiguration configuration) { - public Startup(IConfiguration configuration) - { - Configuration = configuration; - } + Configuration = configuration; + } - public IConfiguration Configuration { get; } + public IConfiguration Configuration { get; } - // This method gets called by the runtime. Use this method to add services to the IoC container. - public void ConfigureServices(IServiceCollection services) - { - services.AddControllersWithViews() - .Services - .AddAppInsight(Configuration) - .AddHealthChecks(Configuration) - .AddCustomMvc(Configuration) - .AddDevspaces() - .AddHttpClientServices(Configuration); + // This method gets called by the runtime. Use this method to add services to the IoC container. + public void ConfigureServices(IServiceCollection services) + { + services.AddControllersWithViews() + .Services + .AddAppInsight(Configuration) + .AddHealthChecks(Configuration) + .AddCustomMvc(Configuration) + .AddDevspaces() + .AddHttpClientServices(Configuration); - IdentityModelEventSource.ShowPII = true; // Caution! Do NOT use in production: https://aka.ms/IdentityModel/PII + IdentityModelEventSource.ShowPII = true; // Caution! Do NOT use in production: https://aka.ms/IdentityModel/PII - services.AddControllers(); + services.AddControllers(); - services.AddCustomAuthentication(Configuration); - } + services.AddCustomAuthentication(Configuration); + } - // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. - public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. + public void Configure(IApplicationBuilder app, IWebHostEnvironment env) + { + JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); + if (env.IsDevelopment()) { - JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Remove("sub"); - if (env.IsDevelopment()) - { - app.UseDeveloperExceptionPage(); - } - else - { - app.UseExceptionHandler("/Error"); - } + app.UseDeveloperExceptionPage(); + } + else + { + app.UseExceptionHandler("/Error"); + } - var pathBase = Configuration["PATH_BASE"]; + var pathBase = Configuration["PATH_BASE"]; - if (!string.IsNullOrEmpty(pathBase)) - { - app.UsePathBase(pathBase); - } + if (!string.IsNullOrEmpty(pathBase)) + { + app.UsePathBase(pathBase); + } - app.UseStaticFiles(); - app.UseSession(); + app.UseStaticFiles(); + app.UseSession(); - WebContextSeed.Seed(app, env); + WebContextSeed.Seed(app, env); - // Fix samesite issue when running eShop from docker-compose locally as by default http protocol is being used - // Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391 - app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = AspNetCore.Http.SameSiteMode.Lax }); + // Fix samesite issue when running eShop from docker-compose locally as by default http protocol is being used + // Refer to https://github.com/dotnet-architecture/eShopOnContainers/issues/1391 + app.UseCookiePolicy(new CookiePolicyOptions { MinimumSameSitePolicy = AspNetCore.Http.SameSiteMode.Lax }); - app.UseRouting(); + app.UseRouting(); - app.UseAuthentication(); - app.UseAuthorization(); + app.UseAuthentication(); + app.UseAuthorization(); - app.UseEndpoints(endpoints => + app.UseEndpoints(endpoints => + { + endpoints.MapControllerRoute("default", "{controller=Catalog}/{action=Index}/{id?}"); + endpoints.MapControllerRoute("defaultError", "{controller=Error}/{action=Error}"); + endpoints.MapControllers(); + endpoints.MapHealthChecks("/liveness", new HealthCheckOptions { - endpoints.MapControllerRoute("default", "{controller=Catalog}/{action=Index}/{id?}"); - endpoints.MapControllerRoute("defaultError", "{controller=Error}/{action=Error}"); - endpoints.MapControllers(); - endpoints.MapHealthChecks("/liveness", new HealthCheckOptions - { - Predicate = r => r.Name.Contains("self") - }); - endpoints.MapHealthChecks("/hc", new HealthCheckOptions() - { - Predicate = _ => true, - ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse - }); + Predicate = r => r.Name.Contains("self") }); - } + endpoints.MapHealthChecks("/hc", new HealthCheckOptions() + { + Predicate = _ => true, + ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse + }); + }); } +} + +static class ServiceCollectionExtensions +{ - static class ServiceCollectionExtensions + public static IServiceCollection AddAppInsight(this IServiceCollection services, IConfiguration configuration) { + services.AddApplicationInsightsTelemetry(configuration); + services.AddApplicationInsightsKubernetesEnricher(); - public static IServiceCollection AddAppInsight(this IServiceCollection services, IConfiguration configuration) - { - services.AddApplicationInsightsTelemetry(configuration); - services.AddApplicationInsightsKubernetesEnricher(); + return services; + } - return services; - } + public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) + { + services.AddHealthChecks() + .AddCheck("self", () => HealthCheckResult.Healthy()) + .AddUrlGroup(new Uri(configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }); - public static IServiceCollection AddHealthChecks(this IServiceCollection services, IConfiguration configuration) - { - services.AddHealthChecks() - .AddCheck("self", () => HealthCheckResult.Healthy()) - .AddUrlGroup(new Uri(configuration["IdentityUrlHC"]), name: "identityapi-check", tags: new string[] { "identityapi" }); + return services; + } - return services; - } + public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) + { + services.AddOptions(); + services.Configure(configuration); + services.AddSession(); + services.AddDistributedMemoryCache(); - public static IServiceCollection AddCustomMvc(this IServiceCollection services, IConfiguration configuration) + if (configuration.GetValue("IsClusterEnv") == bool.TrueString) { - services.AddOptions(); - services.Configure(configuration); - services.AddSession(); - services.AddDistributedMemoryCache(); - - if (configuration.GetValue("IsClusterEnv") == bool.TrueString) + services.AddDataProtection(opts => { - services.AddDataProtection(opts => - { - opts.ApplicationDiscriminator = "eshop.webmvc"; - }) - .PersistKeysToStackExchangeRedis(ConnectionMultiplexer.Connect(configuration["DPConnectionString"]), "DataProtection-Keys"); - } - - return services; + opts.ApplicationDiscriminator = "eshop.webmvc"; + }) + .PersistKeysToStackExchangeRedis(ConnectionMultiplexer.Connect(configuration["DPConnectionString"]), "DataProtection-Keys"); } - // Adds all Http client services - public static IServiceCollection AddHttpClientServices(this IServiceCollection services, IConfiguration configuration) - { - services.AddSingleton(); + return services; + } - //register delegating handlers - services.AddTransient(); - services.AddTransient(); + // Adds all Http client services + public static IServiceCollection AddHttpClientServices(this IServiceCollection services, IConfiguration configuration) + { + services.AddSingleton(); - //set 5 min as the lifetime for each HttpMessageHandler int the pool - services.AddHttpClient("extendedhandlerlifetime").SetHandlerLifetime(TimeSpan.FromMinutes(5)).AddDevspacesSupport(); + //register delegating handlers + services.AddTransient(); + services.AddTransient(); - //add http client services - services.AddHttpClient() - .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Sample. Default lifetime is 2 minutes - .AddHttpMessageHandler() - .AddDevspacesSupport(); + //set 5 min as the lifetime for each HttpMessageHandler int the pool + services.AddHttpClient("extendedhandlerlifetime").SetHandlerLifetime(TimeSpan.FromMinutes(5)).AddDevspacesSupport(); - services.AddHttpClient() - .AddDevspacesSupport(); + //add http client services + services.AddHttpClient() + .SetHandlerLifetime(TimeSpan.FromMinutes(5)) //Sample. Default lifetime is 2 minutes + .AddHttpMessageHandler() + .AddDevspacesSupport(); - services.AddHttpClient() - .AddHttpMessageHandler() - .AddHttpMessageHandler() - .AddDevspacesSupport(); + services.AddHttpClient() + .AddDevspacesSupport(); + services.AddHttpClient() + .AddHttpMessageHandler() + .AddHttpMessageHandler() + .AddDevspacesSupport(); - //add custom application services - services.AddTransient, IdentityParser>(); - return services; - } + //add custom application services + services.AddTransient, IdentityParser>(); + return services; + } - public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) - { - var identityUrl = configuration.GetValue("IdentityUrl"); - var callBackUrl = configuration.GetValue("CallBackUrl"); - var sessionCookieLifetime = configuration.GetValue("SessionCookieLifetimeMinutes", 60); - // Add Authentication services + public static IServiceCollection AddCustomAuthentication(this IServiceCollection services, IConfiguration configuration) + { + var identityUrl = configuration.GetValue("IdentityUrl"); + var callBackUrl = configuration.GetValue("CallBackUrl"); + var sessionCookieLifetime = configuration.GetValue("SessionCookieLifetimeMinutes", 60); - services.AddAuthentication(options => - { - options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - }) - .AddCookie(setup => setup.ExpireTimeSpan = TimeSpan.FromMinutes(sessionCookieLifetime)) - .AddOpenIdConnect(options => - { - options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; - options.Authority = identityUrl.ToString(); - options.SignedOutRedirectUri = callBackUrl.ToString(); - options.ClientId = "mvc"; - options.ClientSecret = "secret"; - options.ResponseType = "code id_token"; - options.SaveTokens = true; - options.GetClaimsFromUserInfoEndpoint = true; - options.RequireHttpsMetadata = false; - options.Scope.Add("openid"); - options.Scope.Add("profile"); - options.Scope.Add("orders"); - options.Scope.Add("basket"); - options.Scope.Add("webshoppingagg"); - options.Scope.Add("orders.signalrhub"); - }); + // Add Authentication services - return services; - } + services.AddAuthentication(options => + { + options.DefaultScheme = CookieAuthenticationDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + }) + .AddCookie(setup => setup.ExpireTimeSpan = TimeSpan.FromMinutes(sessionCookieLifetime)) + .AddOpenIdConnect(options => + { + options.SignInScheme = CookieAuthenticationDefaults.AuthenticationScheme; + options.Authority = identityUrl.ToString(); + options.SignedOutRedirectUri = callBackUrl.ToString(); + options.ClientId = "mvc"; + options.ClientSecret = "secret"; + options.ResponseType = "code id_token"; + options.SaveTokens = true; + options.GetClaimsFromUserInfoEndpoint = true; + options.RequireHttpsMetadata = false; + options.Scope.Add("openid"); + options.Scope.Add("profile"); + options.Scope.Add("orders"); + options.Scope.Add("basket"); + options.Scope.Add("webshoppingagg"); + options.Scope.Add("orders.signalrhub"); + }); + + return services; } } diff --git a/src/Web/WebMVC/ViewComponents/Cart.cs b/src/Web/WebMVC/ViewComponents/Cart.cs index 0fa004a49..8ec80fa91 100644 --- a/src/Web/WebMVC/ViewComponents/Cart.cs +++ b/src/Web/WebMVC/ViewComponents/Cart.cs @@ -1,37 +1,30 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.eShopOnContainers.WebMVC.Services; -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using Microsoft.eShopOnContainers.WebMVC.ViewModels.CartViewModels; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.WebMVC.ViewComponents; -namespace Microsoft.eShopOnContainers.WebMVC.ViewComponents +public class Cart : ViewComponent { - public class Cart : ViewComponent - { - private readonly IBasketService _cartSvc; + private readonly IBasketService _cartSvc; - public Cart(IBasketService cartSvc) => _cartSvc = cartSvc; + public Cart(IBasketService cartSvc) => _cartSvc = cartSvc; - public async Task InvokeAsync(ApplicationUser user) + public async Task InvokeAsync(ApplicationUser user) + { + var vm = new CartComponentViewModel(); + try { - var vm = new CartComponentViewModel(); - try - { - var itemsInCart = await ItemsInCartAsync(user); - vm.ItemsCount = itemsInCart; - return View(vm); - } - catch - { - ViewBag.IsBasketInoperative = true; - } - + var itemsInCart = await ItemsInCartAsync(user); + vm.ItemsCount = itemsInCart; return View(vm); } - private async Task ItemsInCartAsync(ApplicationUser user) + catch { - var basket = await _cartSvc.GetBasket(user); - return basket.Items.Count; + ViewBag.IsBasketInoperative = true; } + + return View(vm); + } + private async Task ItemsInCartAsync(ApplicationUser user) + { + var basket = await _cartSvc.GetBasket(user); + return basket.Items.Count; } } diff --git a/src/Web/WebMVC/ViewComponents/CartList.cs b/src/Web/WebMVC/ViewComponents/CartList.cs index f572c8437..469fc4f4b 100644 --- a/src/Web/WebMVC/ViewComponents/CartList.cs +++ b/src/Web/WebMVC/ViewComponents/CartList.cs @@ -1,33 +1,26 @@ -using Microsoft.AspNetCore.Mvc; -using Microsoft.eShopOnContainers.WebMVC.Services; -using Microsoft.eShopOnContainers.WebMVC.ViewModels; -using System; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.WebMVC.ViewComponents; -namespace Microsoft.eShopOnContainers.WebMVC.ViewComponents +public class CartList : ViewComponent { - public class CartList : ViewComponent - { - private readonly IBasketService _cartSvc; + private readonly IBasketService _cartSvc; - public CartList(IBasketService cartSvc) => _cartSvc = cartSvc; + public CartList(IBasketService cartSvc) => _cartSvc = cartSvc; - public async Task InvokeAsync(ApplicationUser user) + public async Task InvokeAsync(ApplicationUser user) + { + var vm = new Basket(); + try { - var vm = new Basket(); - try - { - vm = await GetItemsAsync(user); - return View(vm); - } - catch (Exception ex) - { - ViewBag.BasketInoperativeMsg = $"Basket Service is inoperative, please try later on. ({ex.GetType().Name} - {ex.Message}))"; - } - + vm = await GetItemsAsync(user); return View(vm); } + catch (Exception ex) + { + ViewBag.BasketInoperativeMsg = $"Basket Service is inoperative, please try later on. ({ex.GetType().Name} - {ex.Message}))"; + } - private Task GetItemsAsync(ApplicationUser user) => _cartSvc.GetBasket(user); + return View(vm); } + + private Task GetItemsAsync(ApplicationUser user) => _cartSvc.GetBasket(user); } diff --git a/src/Web/WebMVC/ViewModels/Annotations/CardExpiration.cs b/src/Web/WebMVC/ViewModels/Annotations/CardExpiration.cs index 3819f6fb0..52c6376d3 100644 --- a/src/Web/WebMVC/ViewModels/Annotations/CardExpiration.cs +++ b/src/Web/WebMVC/ViewModels/Annotations/CardExpiration.cs @@ -1,31 +1,27 @@ -using System; -using System.ComponentModel.DataAnnotations; +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.Annotations; -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.Annotations +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] +public class CardExpirationAttribute : ValidationAttribute { - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] - public class CardExpirationAttribute : ValidationAttribute + public override bool IsValid(object value) { - public override bool IsValid(object value) - { - if (value == null) - return false; + if (value == null) + return false; - var monthString = value.ToString().Split('/')[0]; - var yearString = $"20{value.ToString().Split('/')[1]}"; - // Use the 'out' variable initializer to simplify - // the logic of validating the expiration date - if ((int.TryParse(monthString, out var month)) && - (int.TryParse(yearString, out var year))) - { - DateTime d = new DateTime(year, month, 1); + var monthString = value.ToString().Split('/')[0]; + var yearString = $"20{value.ToString().Split('/')[1]}"; + // Use the 'out' variable initializer to simplify + // the logic of validating the expiration date + if ((int.TryParse(monthString, out var month)) && + (int.TryParse(yearString, out var year))) + { + DateTime d = new DateTime(year, month, 1); - return d > DateTime.UtcNow; - } - else - { - return false; - } + return d > DateTime.UtcNow; + } + else + { + return false; } } } diff --git a/src/Web/WebMVC/ViewModels/Annotations/LatitudeCoordinate.cs b/src/Web/WebMVC/ViewModels/Annotations/LatitudeCoordinate.cs index 5731b8895..dbdf65662 100644 --- a/src/Web/WebMVC/ViewModels/Annotations/LatitudeCoordinate.cs +++ b/src/Web/WebMVC/ViewModels/Annotations/LatitudeCoordinate.cs @@ -1,22 +1,18 @@ -using System; -using System.ComponentModel.DataAnnotations; +namespace WebMVC.ViewModels.Annotations; -namespace WebMVC.ViewModels.Annotations +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] +public class LatitudeCoordinate : ValidationAttribute { - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] - public class LatitudeCoordinate : ValidationAttribute + protected override ValidationResult + IsValid(object value, ValidationContext validationContext) { - protected override ValidationResult - IsValid(object value, ValidationContext validationContext) + double coordinate; + if (!double.TryParse(value.ToString(), out coordinate) || (coordinate < -90 || coordinate > 90)) { - double coordinate; - if (!double.TryParse(value.ToString(), out coordinate) || (coordinate < -90 || coordinate > 90)) - { - return new ValidationResult - ("Latitude must be between -90 and 90 degrees inclusive."); - } - - return ValidationResult.Success; + return new ValidationResult + ("Latitude must be between -90 and 90 degrees inclusive."); } + + return ValidationResult.Success; } } diff --git a/src/Web/WebMVC/ViewModels/Annotations/LongitudeCoordinate.cs b/src/Web/WebMVC/ViewModels/Annotations/LongitudeCoordinate.cs index de1f5cd3e..f0c0dbb32 100644 --- a/src/Web/WebMVC/ViewModels/Annotations/LongitudeCoordinate.cs +++ b/src/Web/WebMVC/ViewModels/Annotations/LongitudeCoordinate.cs @@ -1,22 +1,18 @@ -using System; -using System.ComponentModel.DataAnnotations; +namespace WebMVC.ViewModels.Annotations; -namespace WebMVC.ViewModels.Annotations +[AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] +public class LongitudeCoordinate : ValidationAttribute { - [AttributeUsage(AttributeTargets.Property | AttributeTargets.Field, AllowMultiple = true)] - public class LongitudeCoordinate : ValidationAttribute + protected override ValidationResult + IsValid(object value, ValidationContext validationContext) { - protected override ValidationResult - IsValid(object value, ValidationContext validationContext) + double coordinate; + if (!double.TryParse(value.ToString(), out coordinate) || (coordinate < -180 || coordinate > 180)) { - double coordinate; - if (!double.TryParse(value.ToString(), out coordinate) || (coordinate < -180 || coordinate > 180)) - { - return new ValidationResult - ("Longitude must be between -180 and 180 degrees inclusive."); - } - - return ValidationResult.Success; + return new ValidationResult + ("Longitude must be between -180 and 180 degrees inclusive."); } + + return ValidationResult.Success; } } diff --git a/src/Web/WebMVC/ViewModels/ApplicationUser.cs b/src/Web/WebMVC/ViewModels/ApplicationUser.cs index ec0318850..a8473c7e8 100644 --- a/src/Web/WebMVC/ViewModels/ApplicationUser.cs +++ b/src/Web/WebMVC/ViewModels/ApplicationUser.cs @@ -1,28 +1,24 @@ -using Microsoft.AspNetCore.Identity; -using System.ComponentModel.DataAnnotations; +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels; -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels +// Add profile data for application users by adding properties to the ApplicationUser class +public class ApplicationUser : IdentityUser { - // Add profile data for application users by adding properties to the ApplicationUser class - public class ApplicationUser : IdentityUser - { - public string CardNumber { get; set; } - public string SecurityNumber { get; set; } - public string Expiration { get; set; } - public string CardHolderName { get; set; } - public int CardType { get; set; } - public string Street { get; set; } - public string City { get; set; } - public string State { get; set; } - public string StateCode { get; set; } - public string Country { get; set; } - public string CountryCode { get; set; } - public string ZipCode { get; set; } - public double Latitude { get; set; } - public double Longitude { get; set; } - [Required] - public string Name { get; set; } - [Required] - public string LastName { get; set; } - } + public string CardNumber { get; set; } + public string SecurityNumber { get; set; } + public string Expiration { get; set; } + public string CardHolderName { get; set; } + public int CardType { get; set; } + public string Street { get; set; } + public string City { get; set; } + public string State { get; set; } + public string StateCode { get; set; } + public string Country { get; set; } + public string CountryCode { get; set; } + public string ZipCode { get; set; } + public double Latitude { get; set; } + public double Longitude { get; set; } + [Required] + public string Name { get; set; } + [Required] + public string LastName { get; set; } } diff --git a/src/Web/WebMVC/ViewModels/Basket.cs b/src/Web/WebMVC/ViewModels/Basket.cs index 24c4ca30b..8369b7cc7 100644 --- a/src/Web/WebMVC/ViewModels/Basket.cs +++ b/src/Web/WebMVC/ViewModels/Basket.cs @@ -1,21 +1,16 @@ -using System; -using System.Collections.Generic; -using System.Linq; +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels; -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels +public record Basket { - public record Basket - { - // Use property initializer syntax. - // While this is often more useful for read only - // auto implemented properties, it can simplify logic - // for read/write properties. - public List Items { get; init; } = new List(); - public string BuyerId { get; init; } + // Use property initializer syntax. + // While this is often more useful for read only + // auto implemented properties, it can simplify logic + // for read/write properties. + public List Items { get; init; } = new List(); + public string BuyerId { get; init; } - public decimal Total() - { - return Math.Round(Items.Sum(x => x.UnitPrice * x.Quantity), 2); - } + public decimal Total() + { + return Math.Round(Items.Sum(x => x.UnitPrice * x.Quantity), 2); } } diff --git a/src/Web/WebMVC/ViewModels/BasketItem.cs b/src/Web/WebMVC/ViewModels/BasketItem.cs index 28d0752c6..faf503be0 100644 --- a/src/Web/WebMVC/ViewModels/BasketItem.cs +++ b/src/Web/WebMVC/ViewModels/BasketItem.cs @@ -1,13 +1,12 @@ -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels; + +public record BasketItem { - public record BasketItem - { - public string Id { get; init; } - public int ProductId { get; init; } - public string ProductName { get; init; } - public decimal UnitPrice { get; init; } - public decimal OldUnitPrice { get; init; } - public int Quantity { get; init; } - public string PictureUrl { get; init; } - } + public string Id { get; init; } + public int ProductId { get; init; } + public string ProductName { get; init; } + public decimal UnitPrice { get; init; } + public decimal OldUnitPrice { get; init; } + public int Quantity { get; init; } + public string PictureUrl { get; init; } } diff --git a/src/Web/WebMVC/ViewModels/Campaign.cs b/src/Web/WebMVC/ViewModels/Campaign.cs index eae64c39c..5a295e3a2 100644 --- a/src/Web/WebMVC/ViewModels/Campaign.cs +++ b/src/Web/WebMVC/ViewModels/Campaign.cs @@ -1,12 +1,9 @@ -using System.Collections.Generic; +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels; -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels +public record Campaign { - public record Campaign - { - public int PageIndex { get; init; } - public int PageSize { get; init; } - public int Count { get; init; } - public List Data { get; init; } - } -} \ No newline at end of file + public int PageIndex { get; init; } + public int PageSize { get; init; } + public int Count { get; init; } + public List Data { get; init; } +} diff --git a/src/Web/WebMVC/ViewModels/CampaignItem.cs b/src/Web/WebMVC/ViewModels/CampaignItem.cs index df5639fc2..6fd07b501 100644 --- a/src/Web/WebMVC/ViewModels/CampaignItem.cs +++ b/src/Web/WebMVC/ViewModels/CampaignItem.cs @@ -1,20 +1,17 @@ -using System; +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels; -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels +public record CampaignItem { - public record CampaignItem - { - public int Id { get; init; } + public int Id { get; init; } - public string Name { get; init; } + public string Name { get; init; } - public string Description { get; init; } + public string Description { get; init; } - public DateTime From { get; init; } + public DateTime From { get; init; } - public DateTime To { get; init; } + public DateTime To { get; init; } - public string PictureUri { get; init; } - public string DetailsUri { get; init; } - } -} \ No newline at end of file + public string PictureUri { get; init; } + public string DetailsUri { get; init; } +} diff --git a/src/Web/WebMVC/ViewModels/CartViewModels/IndexViewModel.cs b/src/Web/WebMVC/ViewModels/CartViewModels/IndexViewModel.cs index be7d6dd1f..cc7312f3e 100644 --- a/src/Web/WebMVC/ViewModels/CartViewModels/IndexViewModel.cs +++ b/src/Web/WebMVC/ViewModels/CartViewModels/IndexViewModel.cs @@ -1,8 +1,7 @@ -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.CartViewModels +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.CartViewModels; + +public class CartComponentViewModel { - public class CartComponentViewModel - { - public int ItemsCount { get; set; } - public string Disabled => (ItemsCount == 0) ? "is-disabled" : ""; - } + public int ItemsCount { get; set; } + public string Disabled => (ItemsCount == 0) ? "is-disabled" : ""; } diff --git a/src/Web/WebMVC/ViewModels/Catalog.cs b/src/Web/WebMVC/ViewModels/Catalog.cs index 60a9cc506..8851982c0 100644 --- a/src/Web/WebMVC/ViewModels/Catalog.cs +++ b/src/Web/WebMVC/ViewModels/Catalog.cs @@ -1,12 +1,9 @@ -using System.Collections.Generic; +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels; -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels +public record Catalog { - public record Catalog - { - public int PageIndex { get; init; } - public int PageSize { get; init; } - public int Count { get; init; } - public List Data { get; init; } - } + public int PageIndex { get; init; } + public int PageSize { get; init; } + public int Count { get; init; } + public List Data { get; init; } } diff --git a/src/Web/WebMVC/ViewModels/CatalogItem.cs b/src/Web/WebMVC/ViewModels/CatalogItem.cs index 7663fdf5c..2576da08b 100644 --- a/src/Web/WebMVC/ViewModels/CatalogItem.cs +++ b/src/Web/WebMVC/ViewModels/CatalogItem.cs @@ -1,15 +1,14 @@ -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels; + +public record CatalogItem { - public record CatalogItem - { - public int Id { get; init; } - public string Name { get; init; } - public string Description { get; init; } - public decimal Price { get; init; } - public string PictureUri { get; init; } - public int CatalogBrandId { get; init; } - public string CatalogBrand { get; init; } - public int CatalogTypeId { get; init; } - public string CatalogType { get; init; } - } -} \ No newline at end of file + public int Id { get; init; } + public string Name { get; init; } + public string Description { get; init; } + public decimal Price { get; init; } + public string PictureUri { get; init; } + public int CatalogBrandId { get; init; } + public string CatalogBrand { get; init; } + public int CatalogTypeId { get; init; } + public string CatalogType { get; init; } +} diff --git a/src/Web/WebMVC/ViewModels/CatalogViewModels/IndexViewModel.cs b/src/Web/WebMVC/ViewModels/CatalogViewModels/IndexViewModel.cs index 8f70b32d9..7ebe6f37f 100644 --- a/src/Web/WebMVC/ViewModels/CatalogViewModels/IndexViewModel.cs +++ b/src/Web/WebMVC/ViewModels/CatalogViewModels/IndexViewModel.cs @@ -1,16 +1,11 @@ -using Microsoft.AspNetCore.Mvc.Rendering; -using Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination; -using System.Collections.Generic; +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels; -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.CatalogViewModels +public class IndexViewModel { - public class IndexViewModel - { - public IEnumerable CatalogItems { get; set; } - public IEnumerable Brands { get; set; } - public IEnumerable Types { get; set; } - public int? BrandFilterApplied { get; set; } - public int? TypesFilterApplied { get; set; } - public PaginationInfo PaginationInfo { get; set; } - } + public IEnumerable CatalogItems { get; set; } + public IEnumerable Brands { get; set; } + public IEnumerable Types { get; set; } + public int? BrandFilterApplied { get; set; } + public int? TypesFilterApplied { get; set; } + public PaginationInfo PaginationInfo { get; set; } } diff --git a/src/Web/WebMVC/ViewModels/Converters/NumberToStringConverter.cs b/src/Web/WebMVC/ViewModels/Converters/NumberToStringConverter.cs index cd5b8275a..43a445c30 100644 --- a/src/Web/WebMVC/ViewModels/Converters/NumberToStringConverter.cs +++ b/src/Web/WebMVC/ViewModels/Converters/NumberToStringConverter.cs @@ -1,34 +1,26 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text.Json; -using System.Text.Json.Serialization; -using System.Threading.Tasks; +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels; -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels +public class NumberToStringConverter : JsonConverter { - public class NumberToStringConverter : JsonConverter + public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { - public override string Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) + if (reader.TokenType == JsonTokenType.Number) { - if (reader.TokenType == JsonTokenType.Number) - { - var numberValue = reader.GetInt32(); - return numberValue.ToString(); - } - else if (reader.TokenType == JsonTokenType.String) - { - return reader.GetString(); - } - else - { - throw new JsonException(); - } + var numberValue = reader.GetInt32(); + return numberValue.ToString(); } - - public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) + else if (reader.TokenType == JsonTokenType.String) + { + return reader.GetString(); + } + else { - writer.WriteStringValue(value); + throw new JsonException(); } } + + public override void Write(Utf8JsonWriter writer, string value, JsonSerializerOptions options) + { + writer.WriteStringValue(value); + } } diff --git a/src/Web/WebMVC/ViewModels/Header.cs b/src/Web/WebMVC/ViewModels/Header.cs index ba1126fad..f3bb8f8a6 100644 --- a/src/Web/WebMVC/ViewModels/Header.cs +++ b/src/Web/WebMVC/ViewModels/Header.cs @@ -1,8 +1,7 @@ -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels; + +public record Header { - public record Header - { - public string Controller { get; init; } - public string Text { get; init; } - } -} \ No newline at end of file + public string Controller { get; init; } + public string Text { get; init; } +} diff --git a/src/Web/WebMVC/ViewModels/Order.cs b/src/Web/WebMVC/ViewModels/Order.cs index 475f1cbe3..af358336a 100644 --- a/src/Web/WebMVC/ViewModels/Order.cs +++ b/src/Web/WebMVC/ViewModels/Order.cs @@ -1,101 +1,91 @@ -using Microsoft.AspNetCore.Mvc.Rendering; -using Microsoft.eShopOnContainers.WebMVC.ViewModels.Annotations; -using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.ComponentModel.DataAnnotations; -using System.Text.Json.Serialization; -using WebMVC.Services.ModelDTOs; - -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels -{ - public class Order - { - [JsonConverter(typeof(NumberToStringConverter))] - public string OrderNumber { get; set; } - - public DateTime Date { get; set; } - - public string Status { get; set; } - - public decimal Total { get; set; } - - public string Description { get; set; } - - [Required] - public string City { get; set; } - [Required] - public string Street { get; set; } - [Required] - public string State { get; set; } - [Required] - public string Country { get; set; } - - public string ZipCode { get; set; } - [Required] - [DisplayName("Card number")] - public string CardNumber { get; set; } - [Required] - [DisplayName("Cardholder name")] - public string CardHolderName { get; set; } - - public DateTime CardExpiration { get; set; } - [RegularExpression(@"(0[1-9]|1[0-2])\/[0-9]{2}", ErrorMessage = "Expiration should match a valid MM/YY value")] - [CardExpiration(ErrorMessage = "The card is expired"), Required] - [DisplayName("Card expiration")] - public string CardExpirationShort { get; set; } - [Required] - [DisplayName("Card security number")] - public string CardSecurityNumber { get; set; } - - public int CardTypeId { get; set; } - - public string Buyer { get; set; } - - public List ActionCodeSelectList => - GetActionCodesByCurrentState(); +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels; + +public class Order +{ + [JsonConverter(typeof(NumberToStringConverter))] + public string OrderNumber { get; set; } + + public DateTime Date { get; set; } + + public string Status { get; set; } + + public decimal Total { get; set; } + + public string Description { get; set; } + + [Required] + public string City { get; set; } + [Required] + public string Street { get; set; } + [Required] + public string State { get; set; } + [Required] + public string Country { get; set; } + + public string ZipCode { get; set; } + [Required] + [DisplayName("Card number")] + public string CardNumber { get; set; } + [Required] + [DisplayName("Cardholder name")] + public string CardHolderName { get; set; } + + public DateTime CardExpiration { get; set; } + [RegularExpression(@"(0[1-9]|1[0-2])\/[0-9]{2}", ErrorMessage = "Expiration should match a valid MM/YY value")] + [CardExpiration(ErrorMessage = "The card is expired"), Required] + [DisplayName("Card expiration")] + public string CardExpirationShort { get; set; } + [Required] + [DisplayName("Card security number")] + public string CardSecurityNumber { get; set; } + + public int CardTypeId { get; set; } + + public string Buyer { get; set; } + + public List ActionCodeSelectList => + GetActionCodesByCurrentState(); - public List OrderItems { get; set; } + public List OrderItems { get; set; } - [Required] - public Guid RequestId { get; set; } + [Required] + public Guid RequestId { get; set; } - public void CardExpirationShortFormat() - { - CardExpirationShort = CardExpiration.ToString("MM/yy"); - } + public void CardExpirationShortFormat() + { + CardExpirationShort = CardExpiration.ToString("MM/yy"); + } - public void CardExpirationApiFormat() - { - var month = CardExpirationShort.Split('/')[0]; - var year = $"20{CardExpirationShort.Split('/')[1]}"; + public void CardExpirationApiFormat() + { + var month = CardExpirationShort.Split('/')[0]; + var year = $"20{CardExpirationShort.Split('/')[1]}"; - CardExpiration = new DateTime(int.Parse(year), int.Parse(month), 1); - } + CardExpiration = new DateTime(int.Parse(year), int.Parse(month), 1); + } - private List GetActionCodesByCurrentState() + private List GetActionCodesByCurrentState() + { + var actions = new List(); + switch (Status?.ToLower()) { - var actions = new List(); - switch (Status?.ToLower()) - { - case "paid": - actions.Add(OrderProcessAction.Ship); - break; - } - - var result = new List(); - actions.ForEach(action => - { - result.Add(new SelectListItem { Text = action.Name, Value = action.Code }); - }); - - return result; + case "paid": + actions.Add(OrderProcessAction.Ship); + break; } - } - public enum CardType - { - AMEX = 1 + var result = new List(); + actions.ForEach(action => + { + result.Add(new SelectListItem { Text = action.Name, Value = action.Code }); + }); + + return result; } } + +public enum CardType +{ + AMEX = 1 +} diff --git a/src/Web/WebMVC/ViewModels/OrderItem.cs b/src/Web/WebMVC/ViewModels/OrderItem.cs index c63dcc988..05b2960f6 100644 --- a/src/Web/WebMVC/ViewModels/OrderItem.cs +++ b/src/Web/WebMVC/ViewModels/OrderItem.cs @@ -1,17 +1,16 @@ -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels; + +public record OrderItem { - public record OrderItem - { - public int ProductId { get; init; } + public int ProductId { get; init; } - public string ProductName { get; init; } + public string ProductName { get; init; } - public decimal UnitPrice { get; init; } + public decimal UnitPrice { get; init; } - public decimal Discount { get; init; } + public decimal Discount { get; init; } - public int Units { get; init; } + public int Units { get; init; } - public string PictureUrl { get; init; } - } + public string PictureUrl { get; init; } } diff --git a/src/Web/WebMVC/ViewModels/Pagination/PaginationInfo.cs b/src/Web/WebMVC/ViewModels/Pagination/PaginationInfo.cs index a10280659..d06890673 100644 --- a/src/Web/WebMVC/ViewModels/Pagination/PaginationInfo.cs +++ b/src/Web/WebMVC/ViewModels/Pagination/PaginationInfo.cs @@ -1,12 +1,11 @@ -namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination +namespace Microsoft.eShopOnContainers.WebMVC.ViewModels.Pagination; + +public class PaginationInfo { - public class PaginationInfo - { - public int TotalItems { get; set; } - public int ItemsPerPage { get; set; } - public int ActualPage { get; set; } - public int TotalPages { get; set; } - public string Previous { get; set; } - public string Next { get; set; } - } + public int TotalItems { get; set; } + public int ItemsPerPage { get; set; } + public int ActualPage { get; set; } + public int TotalPages { get; set; } + public string Previous { get; set; } + public string Next { get; set; } }