From ffc7c0683b49975b3f0e58f7f1f3e73cc400e5f1 Mon Sep 17 00:00:00 2001 From: Claudio Pi Date: Fri, 20 Oct 2023 18:48:33 -0300 Subject: [PATCH] Added CA and Stylecop rules to NorthwindCRUD project. --- NorthwindCRUD.Tests/CategroyServiceFixture.cs | 5 +- NorthwindCRUD.Tests/CustomerServiceFixture.cs | 1 + NorthwindCRUD.Tests/EmployeeServiceFixture.cs | 11 +- NorthwindCRUD.Tests/OrderServiceFixture.cs | 3 + NorthwindCRUD.Tests/ProductServiceFixture.cs | 4 +- NorthwindCRUD.Tests/RegionServiceFixture.cs | 2 + NorthwindCRUD.Tests/ShipperServiceFixture.cs | 2 + NorthwindCRUD.Tests/SupplierServiceFixture.cs | 4 +- .../TerritoryServiceFixture.cs | 4 +- NorthwindCRUD/Controllers/AuthController.cs | 4 +- .../Controllers/CategoriesController.cs | 12 +- .../Controllers/EmployeesController.cs | 6 + NorthwindCRUD/Controllers/OrdersController.cs | 3 +- .../Controllers/ProductsController.cs | 5 +- .../Controllers/RegionsController.cs | 5 +- NorthwindCRUD/Controllers/SalesController.cs | 21 +- .../Controllers/ShippersController.cs | 1 - .../Controllers/SuppliersController.cs | 1 - .../Controllers/TerritoriesController.cs | 19 +- .../ControllersGraphQL/CategoryController.cs | 9 +- .../ControllersGraphQL/CustomerController.cs | 27 +- .../ControllersGraphQL/EmployeeController.cs | 10 +- .../ControllersGraphQL/OrderController.cs | 27 +- NorthwindCRUD/DataContext.cs | 21 +- .../Filters/AuthResponseOperationFilter.cs | 23 +- NorthwindCRUD/Helpers/DBSeeder.cs | 140 +++++--- NorthwindCRUD/Helpers/IdGenerator.cs | 1 + NorthwindCRUD/Helpers/PropertyHelper.cs | 15 +- .../20220908121941_InitialCreate.cs | 3 +- .../20220908134815_UpdateOrdersTable.cs | 3 +- .../20221115201007_AddUsersTable.cs | 5 +- NorthwindCRUD/Models/Contracts/ICategory.cs | 2 +- NorthwindCRUD/Models/Contracts/ICustomer.cs | 2 +- NorthwindCRUD/Models/Contracts/IProduct.cs | 2 +- NorthwindCRUD/Models/Contracts/ISupplier.cs | 22 +- NorthwindCRUD/Models/Contracts/IUser.cs | 2 +- NorthwindCRUD/Models/DbModels/AddressDb.cs | 11 +- NorthwindCRUD/Models/DbModels/CategoryDb.cs | 10 +- NorthwindCRUD/Models/DbModels/CustomerDb.cs | 10 +- NorthwindCRUD/Models/DbModels/EmployeeDb.cs | 12 +- NorthwindCRUD/Models/DbModels/OrderDb.cs | 11 +- NorthwindCRUD/Models/DbModels/ProductDb.cs | 6 +- NorthwindCRUD/Models/DbModels/RegionDb.cs | 4 +- NorthwindCRUD/Models/DbModels/ShipperDb.cs | 4 +- NorthwindCRUD/Models/DbModels/SupplierDb.cs | 4 +- NorthwindCRUD/Models/DbModels/TerritoryDb.cs | 4 +- NorthwindCRUD/Models/DbModels/UserDb.cs | 13 +- NorthwindCRUD/Models/Dtos/AddressDto.cs | 6 +- NorthwindCRUD/Models/Dtos/CustomerDto.cs | 10 +- NorthwindCRUD/Models/Dtos/EmployeeDto.cs | 14 +- .../Models/Dtos/EmployeeTerritoryDto.cs | 5 +- NorthwindCRUD/Models/Dtos/LoginDto.cs | 8 +- NorthwindCRUD/Models/Dtos/RegisterDto.cs | 8 +- NorthwindCRUD/Models/Dtos/SalesDto.cs | 2 + NorthwindCRUD/Models/Dtos/SupplierDto.cs | 22 +- NorthwindCRUD/NorthwindCRUD.csproj | 75 +++-- NorthwindCRUD/Program.cs | 300 +++++++++--------- NorthwindCRUD/Services/AuthService.cs | 35 +- NorthwindCRUD/Services/CategoryService.cs | 8 +- NorthwindCRUD/Services/CustomerService.cs | 19 +- NorthwindCRUD/Services/EmployeeService.cs | 16 +- .../Services/EmployeeTerritoryService.cs | 18 +- NorthwindCRUD/Services/OrderService.cs | 64 ++-- NorthwindCRUD/Services/ProductService.cs | 20 +- NorthwindCRUD/Services/RegionService.cs | 20 +- NorthwindCRUD/Services/SalesService.cs | 26 +- NorthwindCRUD/Services/ShipperService.cs | 9 +- NorthwindCRUD/Services/SupplierService.cs | 10 +- NorthwindCRUD/Services/TerritoryService.cs | 22 +- 69 files changed, 670 insertions(+), 563 deletions(-) diff --git a/NorthwindCRUD.Tests/CategroyServiceFixture.cs b/NorthwindCRUD.Tests/CategroyServiceFixture.cs index 8cbb56e..95de263 100644 --- a/NorthwindCRUD.Tests/CategroyServiceFixture.cs +++ b/NorthwindCRUD.Tests/CategroyServiceFixture.cs @@ -14,8 +14,8 @@ public void ShouldCreateCategory() Assert.IsNotNull(createdCategory); createdCategory = DataHelper2.CategoryService.GetById(createdCategory.CategoryId); - Assert.AreEqual(category.Name, createdCategory.Name); - Assert.AreEqual(category.Description, createdCategory.Description); + Assert.AreEqual(category.Name, createdCategory?.Name); + Assert.AreEqual(category.Description, createdCategory?.Description); } [TestMethod] @@ -32,6 +32,7 @@ public void ShouldUpdateCategory() Assert.IsNotNull(updatedCategory); updatedCategory = DataHelper2.CategoryService.GetById(updatedCategory.CategoryId); + Assert.IsNotNull(updatedCategory); Assert.AreNotEqual(orignalName, updatedCategory.Name); Assert.AreNotEqual(orignalDescription, updatedCategory.Description); Assert.AreEqual(createdCategory.Name, updatedCategory.Name); diff --git a/NorthwindCRUD.Tests/CustomerServiceFixture.cs b/NorthwindCRUD.Tests/CustomerServiceFixture.cs index 22eb860..83ede50 100644 --- a/NorthwindCRUD.Tests/CustomerServiceFixture.cs +++ b/NorthwindCRUD.Tests/CustomerServiceFixture.cs @@ -14,6 +14,7 @@ public void ShouldCreateCustomer() Assert.AreEqual(customer, createdCustomer, "Customers instances should be the same since we are over the same context"); createdCustomer = DataHelper2.CustomerService.GetById(createdCustomer.CustomerId); + Assert.IsNotNull(createdCustomer); Assert.AreNotEqual(customer, createdCustomer, "Customer instances should be different"); Assert.AreEqual(customer.CompanyName, createdCustomer.CompanyName); diff --git a/NorthwindCRUD.Tests/EmployeeServiceFixture.cs b/NorthwindCRUD.Tests/EmployeeServiceFixture.cs index 9192d0c..832881f 100644 --- a/NorthwindCRUD.Tests/EmployeeServiceFixture.cs +++ b/NorthwindCRUD.Tests/EmployeeServiceFixture.cs @@ -14,10 +14,11 @@ public void ShouldCreateEmployee() var createdEmployee = DataHelper.EmployeeService.Create(employee); Assert.IsNotNull(createdEmployee); - var newEmployee = DataHelper2.EmployeeService.GetById(createdEmployee.EmployeeId); - Assert.AreEqual(employee.FirstName, newEmployee.FirstName); - Assert.AreEqual(employee.LastName, newEmployee.LastName); - Assert.AreEqual(employee.Title, newEmployee.Title); + createdEmployee = DataHelper2.EmployeeService.GetById(createdEmployee.EmployeeId); + Assert.IsNotNull(createdEmployee); + Assert.AreEqual(employee.FirstName, createdEmployee.FirstName); + Assert.AreEqual(employee.LastName, createdEmployee.LastName); + Assert.AreEqual(employee.Title, createdEmployee.Title); } [TestMethod] @@ -32,7 +33,7 @@ public void ShouldUpdateEmployee() Assert.IsNotNull(updatedEmployee); updatedEmployee = DataHelper2.EmployeeService.GetById(updatedEmployee.EmployeeId); - + Assert.IsNotNull(updatedEmployee); Assert.AreNotEqual(originalTitle, updatedEmployee.Title); Assert.AreEqual(createdEmployee.Title, updatedEmployee.Title); } diff --git a/NorthwindCRUD.Tests/OrderServiceFixture.cs b/NorthwindCRUD.Tests/OrderServiceFixture.cs index dbe35ce..67aebc7 100644 --- a/NorthwindCRUD.Tests/OrderServiceFixture.cs +++ b/NorthwindCRUD.Tests/OrderServiceFixture.cs @@ -20,6 +20,8 @@ public void ShouldCreateOrder() Assert.IsNotNull(createdOrder); createdOrder = DataHelper2.OrderService.GetById(createdOrder.OrderId); + Assert.IsNotNull(createdOrder); + Assert.AreEqual(order.OrderId, createdOrder.OrderId); Assert.AreEqual(order.CustomerId, createdOrder.CustomerId); Assert.AreEqual(order.EmployeeId, createdOrder.EmployeeId); @@ -39,6 +41,7 @@ public void ShouldUpdateOrder() Assert.IsNotNull(updatedOrder); updatedOrder = DataHelper2.OrderService.GetById(updatedOrder.OrderId); + Assert.IsNotNull(updatedOrder); Assert.AreNotEqual(originalCustomerId, updatedOrder.CustomerId); Assert.AreNotEqual(originalEmployeeId, updatedOrder.EmployeeId); Assert.AreEqual(order.CustomerId, updatedOrder.CustomerId); diff --git a/NorthwindCRUD.Tests/ProductServiceFixture.cs b/NorthwindCRUD.Tests/ProductServiceFixture.cs index 5bcea3c..d3be0ba 100644 --- a/NorthwindCRUD.Tests/ProductServiceFixture.cs +++ b/NorthwindCRUD.Tests/ProductServiceFixture.cs @@ -13,7 +13,7 @@ public void ShouldCreateProduct() Assert.IsNotNull(createdProduct); createdProduct = DataHelper2.ProductService.GetById(createdProduct.ProductId); - + Assert.IsNotNull(createdProduct); Assert.AreEqual(product.UnitPrice, createdProduct.UnitPrice); Assert.AreEqual(product.UnitsInStock, createdProduct.UnitsInStock); } @@ -31,7 +31,7 @@ public void ShouldUpdateProduct() Assert.IsNotNull(updatedProduct); updatedProduct = DataHelper2.ProductService.GetById(updatedProduct.ProductId); - + Assert.IsNotNull(updatedProduct); Assert.AreNotEqual(originaUnitPrice, updatedProduct.UnitPrice); Assert.AreNotEqual(originaUnitsInStock, updatedProduct.UnitsInStock); diff --git a/NorthwindCRUD.Tests/RegionServiceFixture.cs b/NorthwindCRUD.Tests/RegionServiceFixture.cs index 1b99dab..f263088 100644 --- a/NorthwindCRUD.Tests/RegionServiceFixture.cs +++ b/NorthwindCRUD.Tests/RegionServiceFixture.cs @@ -15,6 +15,7 @@ public void ShouldCreateRegion() Assert.IsNotNull(createdRegion); createdRegion = DataHelper2.RegionService.GetById(createdRegion.RegionId); + Assert.IsNotNull(createdRegion); Assert.AreEqual(region.RegionId, createdRegion.RegionId); Assert.AreEqual(region.RegionDescription, createdRegion.RegionDescription); } @@ -30,6 +31,7 @@ public void ShouldUpdateRegion() Assert.IsNotNull(updatedRegion); updatedRegion = DataHelper2.RegionService.GetById(updatedRegion.RegionId); + Assert.IsNotNull(updatedRegion); Assert.AreNotEqual(originalRegionDescription, updatedRegion.RegionDescription); Assert.AreEqual(region.RegionDescription, updatedRegion.RegionDescription); } diff --git a/NorthwindCRUD.Tests/ShipperServiceFixture.cs b/NorthwindCRUD.Tests/ShipperServiceFixture.cs index 701813c..eb6713a 100644 --- a/NorthwindCRUD.Tests/ShipperServiceFixture.cs +++ b/NorthwindCRUD.Tests/ShipperServiceFixture.cs @@ -14,6 +14,7 @@ public void ShouldCreateShipper() Assert.IsNotNull(createdShipper); createdShipper = DataHelper2.ShipperService.GetById(createdShipper.ShipperId); + Assert.IsNotNull(createdShipper); Assert.AreEqual(shipper.ShipperId, createdShipper.ShipperId); Assert.AreEqual(shipper.CompanyName, createdShipper.CompanyName); Assert.AreEqual(shipper.Phone, createdShipper.Phone); @@ -34,6 +35,7 @@ public void ShouldUpdateShipper() Assert.IsNotNull(updatedShipper); updatedShipper = DataHelper2.ShipperService.GetById(updatedShipper.ShipperId); + Assert.IsNotNull(updatedShipper); Assert.AreNotEqual(originalCompanyName, updatedShipper.CompanyName); Assert.AreNotEqual(originalPhone, updatedShipper.Phone); Assert.AreEqual(shipper.CompanyName, updatedShipper.CompanyName); diff --git a/NorthwindCRUD.Tests/SupplierServiceFixture.cs b/NorthwindCRUD.Tests/SupplierServiceFixture.cs index 095b878..60357af 100644 --- a/NorthwindCRUD.Tests/SupplierServiceFixture.cs +++ b/NorthwindCRUD.Tests/SupplierServiceFixture.cs @@ -15,7 +15,7 @@ public void ShouldCreateSupplier() Assert.IsNotNull(createdSupplier); createdSupplier = DataHelper2.SupplierService.GetById(createdSupplier.SupplierId); - + Assert.IsNotNull(createdSupplier); Assert.AreEqual(supplier.SupplierId, createdSupplier.SupplierId); Assert.AreEqual(supplier.CompanyName, createdSupplier.CompanyName); Assert.AreEqual(supplier.ContactName, createdSupplier.ContactName); @@ -35,9 +35,9 @@ public void ShouldUpdateSupplier() supplier.ContactTitle = "Updated Title"; var updatedSupplier = DataHelper.SupplierService.Update(supplier); - Assert.IsNotNull(updatedSupplier); updatedSupplier = DataHelper2.SupplierService.GetById(updatedSupplier.SupplierId); + Assert.IsNotNull(updatedSupplier); Assert.AreEqual(supplier.CompanyName, updatedSupplier.CompanyName); Assert.AreEqual(supplier.ContactName, updatedSupplier.ContactName); Assert.AreEqual(supplier.ContactTitle, updatedSupplier.ContactTitle); diff --git a/NorthwindCRUD.Tests/TerritoryServiceFixture.cs b/NorthwindCRUD.Tests/TerritoryServiceFixture.cs index 3cbc5bc..4747dc3 100644 --- a/NorthwindCRUD.Tests/TerritoryServiceFixture.cs +++ b/NorthwindCRUD.Tests/TerritoryServiceFixture.cs @@ -14,7 +14,7 @@ public void ShouldCreateTerritory() Assert.IsNotNull(createdTerritory); createdTerritory = DataHelper2.TerritoryService.GetById(createdTerritory.TerritoryId); - + Assert.IsNotNull(createdTerritory); Assert.AreEqual(territory.TerritoryId, createdTerritory.TerritoryId); Assert.AreEqual(territory.TerritoryDescription, createdTerritory.TerritoryDescription); Assert.AreEqual(territory.RegionId, createdTerritory.RegionId); @@ -32,8 +32,8 @@ public void ShouldUpdateTerritory() var updatedTerritory = DataHelper.TerritoryService.Update(createdTerritory); Assert.IsNotNull(updatedTerritory); - updatedTerritory = DataHelper2.TerritoryService.GetById(updatedTerritory.TerritoryId); + Assert.IsNotNull(updatedTerritory); Assert.AreNotEqual(originalTerritoryDescription, updatedTerritory.TerritoryDescription); Assert.AreEqual(createdTerritory.TerritoryDescription, updatedTerritory.TerritoryDescription); } diff --git a/NorthwindCRUD/Controllers/AuthController.cs b/NorthwindCRUD/Controllers/AuthController.cs index 4837eb7..4734b72 100644 --- a/NorthwindCRUD/Controllers/AuthController.cs +++ b/NorthwindCRUD/Controllers/AuthController.cs @@ -15,7 +15,7 @@ public class AuthController : Controller private readonly AuthService authService; private readonly IMapper mapper; private readonly ILogger logger; - + public AuthController(IConfiguration configuration, AuthService authService, IMapper mapper, ILogger logger) { this.configuration = configuration; @@ -38,6 +38,7 @@ public ActionResult Login(LoginDto userModel) return Ok(token); } + return BadRequest("Email or password are not correct!"); } @@ -75,7 +76,6 @@ public ActionResult Register(RegisterDto userModel) { var token = this.authService.GenerateJwtToken(user.Email); return Ok(token); - } return BadRequest("Email or password are not correct!"); diff --git a/NorthwindCRUD/Controllers/CategoriesController.cs b/NorthwindCRUD/Controllers/CategoriesController.cs index fc6e38e..52ee360 100644 --- a/NorthwindCRUD/Controllers/CategoriesController.cs +++ b/NorthwindCRUD/Controllers/CategoriesController.cs @@ -21,7 +21,7 @@ public CategoriesController(CategoryService categoryService, ProductService prod this.categoryService = categoryService; this.productService = productService; this.mapper = mapper; - this.logger = logger; + this.logger = logger; } [HttpGet] @@ -30,14 +30,13 @@ public ActionResult GetAll() try { var categories = this.categoryService.GetAll(); - return base.Ok(this.mapper.Map(categories)); + return Ok(this.mapper.Map(categories)); } catch (Exception error) { logger.LogError(error.Message); return StatusCode(500); } - } [HttpGet("{id}")] @@ -48,7 +47,7 @@ public ActionResult GetById(int id) var category = this.categoryService.GetById(id); if (category != null) { - return base.Ok(this.mapper.Map(category)); + return Ok(this.mapper.Map(category)); } return NotFound(); @@ -60,7 +59,6 @@ public ActionResult GetById(int id) } } - [HttpGet("{id}/Details")] public ActionResult GetDetailsById(int id) { @@ -131,7 +129,7 @@ public ActionResult Update(CategoryDto model) if (category != null) { - return base.Ok(this.mapper.Map(category)); + return Ok(this.mapper.Map(category)); } return NotFound(); @@ -155,7 +153,7 @@ public ActionResult Delete(int id) var category = this.categoryService.Delete(id); if (category != null) { - return base.Ok(this.mapper.Map(category)); + return Ok(this.mapper.Map(category)); } return NotFound(); diff --git a/NorthwindCRUD/Controllers/EmployeesController.cs b/NorthwindCRUD/Controllers/EmployeesController.cs index d72d0ec..524adb2 100644 --- a/NorthwindCRUD/Controllers/EmployeesController.cs +++ b/NorthwindCRUD/Controllers/EmployeesController.cs @@ -123,6 +123,11 @@ public ActionResult GetTeritoriesByEmployeeId(int id) try { var teritories = this.employeeTerritoryService.GetTeritoriesByEmployeeId(id); + if (teritories == null) + { + return NotFound($"No territories for employee {id}"); + } + return Ok(this.mapper.Map(teritories)); } catch (Exception error) @@ -144,6 +149,7 @@ public ActionResult AddTerritoryToEmployee(EmployeeTerrito var employeeTerrirtory = this.employeeTerritoryService.AddTerritoryToEmployee(mappedModel); return Ok(this.mapper.Map(employeeTerrirtory)); } + return BadRequest(ModelState); } catch (InvalidOperationException exception) diff --git a/NorthwindCRUD/Controllers/OrdersController.cs b/NorthwindCRUD/Controllers/OrdersController.cs index 0538478..1ace077 100644 --- a/NorthwindCRUD/Controllers/OrdersController.cs +++ b/NorthwindCRUD/Controllers/OrdersController.cs @@ -93,7 +93,7 @@ public ActionResult GetCustomerByOrderId(int id) try { var order = this.orderService.GetById(id); - if (order != null) + if (order != null && order.CustomerId != null) { var customer = this.customerService.GetById(order.CustomerId); @@ -161,7 +161,6 @@ public ActionResult GetShipperByOrderId(int id) } } - [HttpGet("{id}/Products")] public ActionResult GetProductsByOrderId(int id) { diff --git a/NorthwindCRUD/Controllers/ProductsController.cs b/NorthwindCRUD/Controllers/ProductsController.cs index e5f406a..34ca7e0 100644 --- a/NorthwindCRUD/Controllers/ProductsController.cs +++ b/NorthwindCRUD/Controllers/ProductsController.cs @@ -25,7 +25,7 @@ public ProductsController(ProductService productService, CategoryService categor this.orderService = orderService; this.supplierService = supplierService; this.mapper = mapper; - this.logger = logger; + this.logger = logger; } [HttpGet] @@ -41,7 +41,6 @@ public ActionResult GetAll() logger.LogError(error.Message); return StatusCode(500); } - } [HttpGet("{id}")] @@ -76,7 +75,7 @@ public ActionResult GetCategoryByProductId(int id) if (category != null) { - return Ok(this.mapper.Map(category)); + return Ok(this.mapper.Map(category)); } } diff --git a/NorthwindCRUD/Controllers/RegionsController.cs b/NorthwindCRUD/Controllers/RegionsController.cs index f65a5a1..0a6a032 100644 --- a/NorthwindCRUD/Controllers/RegionsController.cs +++ b/NorthwindCRUD/Controllers/RegionsController.cs @@ -38,7 +38,6 @@ public ActionResult GetAll() logger.LogError(error.Message); return StatusCode(500); } - } [HttpGet("{id}")] @@ -90,8 +89,8 @@ public ActionResult Create(RegionDto model) if (ModelState.IsValid) { var mappedModel = this.mapper.Map(model); - var Region = this.regionService.Create(mappedModel); - return Ok(this.mapper.Map(Region)); + var region = this.regionService.Create(mappedModel); + return Ok(this.mapper.Map(region)); } return BadRequest(ModelState); diff --git a/NorthwindCRUD/Controllers/SalesController.cs b/NorthwindCRUD/Controllers/SalesController.cs index 249d2ab..7918af3 100644 --- a/NorthwindCRUD/Controllers/SalesController.cs +++ b/NorthwindCRUD/Controllers/SalesController.cs @@ -1,12 +1,12 @@ -namespace NorthwindCRUD.Controllers -{ - using AutoMapper; - using Microsoft.AspNetCore.Authorization; - using Microsoft.AspNetCore.Mvc; - using NorthwindCRUD.Models.Dtos; - using NorthwindCRUD.Services; - using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; +using AutoMapper; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; +using NorthwindCRUD.Models.Dtos; +using NorthwindCRUD.Services; +namespace NorthwindCRUD.Controllers +{ [ApiController] [Route("[controller]")] public class SalesController : ControllerBase @@ -26,7 +26,8 @@ public SalesController(SalesService salesService, IMapper mapper, ILogger logger [Authorize] public ActionResult GetSalesByCategoryAndYear([FromQuery] [Required] string categoryName, [FromQuery] int? orderYear = null) { - try { + try + { var response = this.salesService.GetSalesDataByCategoryAndYear(categoryName, orderYear); return Ok(response); } @@ -43,7 +44,6 @@ public ActionResult GetSalesByCountry( [FromQuery] [Required] string startDate, [FromQuery] [Required] string endDate) { - try { var salesData = this.salesService.RetrieveSalesDataByCountry(startDate, endDate, country); @@ -73,7 +73,6 @@ public ActionResult GetSalesByYear( [FromQuery] int startMounth, [FromQuery] int endMounth) { - try { var salesData = this.salesService.RetrieveSalesDataByYear(year, startMounth, endMounth); diff --git a/NorthwindCRUD/Controllers/ShippersController.cs b/NorthwindCRUD/Controllers/ShippersController.cs index 3f5d27e..e2142a7 100644 --- a/NorthwindCRUD/Controllers/ShippersController.cs +++ b/NorthwindCRUD/Controllers/ShippersController.cs @@ -38,7 +38,6 @@ public ActionResult GetAll() logger.LogError(error.Message); return StatusCode(500); } - } [HttpGet("{id}")] diff --git a/NorthwindCRUD/Controllers/SuppliersController.cs b/NorthwindCRUD/Controllers/SuppliersController.cs index 4e5399b..7d1a48c 100644 --- a/NorthwindCRUD/Controllers/SuppliersController.cs +++ b/NorthwindCRUD/Controllers/SuppliersController.cs @@ -38,7 +38,6 @@ public ActionResult GetAll() logger.LogError(error.Message); return StatusCode(500); } - } [HttpGet("{id}")] diff --git a/NorthwindCRUD/Controllers/TerritoriesController.cs b/NorthwindCRUD/Controllers/TerritoriesController.cs index d7e159c..28ce174 100644 --- a/NorthwindCRUD/Controllers/TerritoriesController.cs +++ b/NorthwindCRUD/Controllers/TerritoriesController.cs @@ -40,7 +40,6 @@ public ActionResult GetAll() logger.LogError(error.Message); return StatusCode(500); } - } [HttpGet("{id}")] @@ -69,6 +68,11 @@ public ActionResult GetEmployeesByTerritory(string id) try { var employees = this.employeeTerritoryService.GetEmployeesByTerritoryId(id); + if (employees == null) + { + return NotFound($"No employees for territory {id}"); + } + return Ok(this.mapper.Map(employees)); } catch (Exception error) @@ -92,7 +96,6 @@ public ActionResult GetRegionByTerritory(string id) { return Ok(this.mapper.Map(region)); } - } return NotFound(); @@ -139,11 +142,11 @@ public ActionResult Update(TerritoryDto model) if (ModelState.IsValid) { var mappedModel = this.mapper.Map(model); - var Territory = this.territoryService.Update(mappedModel); + var territory = this.territoryService.Update(mappedModel); - if (Territory != null) + if (territory != null) { - return Ok(this.mapper.Map(Territory)); + return Ok(this.mapper.Map(territory)); } return NotFound(); @@ -168,10 +171,10 @@ public ActionResult Delete(string id) { try { - var Territory = this.territoryService.Delete(id); - if (Territory != null) + var territory = this.territoryService.Delete(id); + if (territory != null) { - return Ok(this.mapper.Map(Territory)); + return Ok(this.mapper.Map(territory)); } return NotFound(); diff --git a/NorthwindCRUD/ControllersGraphQL/CategoryController.cs b/NorthwindCRUD/ControllersGraphQL/CategoryController.cs index 0603d99..c5ba167 100644 --- a/NorthwindCRUD/ControllersGraphQL/CategoryController.cs +++ b/NorthwindCRUD/ControllersGraphQL/CategoryController.cs @@ -18,7 +18,7 @@ public CategoryGraphController(CategoryService categoryService, IMapper mapper, { this.categoryService = categoryService; this.mapper = mapper; - this.logger = logger; + this.logger = logger; } [Query] @@ -50,15 +50,16 @@ public CategoryDto Create(CategoryDto model) } [Mutation] - public CategoryDto Update(CategoryDto model) + public CategoryDto? Update(CategoryDto model) { var mappedModel = this.mapper.Map(model); var category = this.categoryService.Update(mappedModel); - return this.mapper.Map(category); + + return category != null ? this.mapper.Map(category) : null; } [Mutation] - public CategoryDto Delete(int id) + public CategoryDto? Delete(int id) { var category = this.categoryService.Delete(id); diff --git a/NorthwindCRUD/ControllersGraphQL/CustomerController.cs b/NorthwindCRUD/ControllersGraphQL/CustomerController.cs index 98f783b..af5d0a1 100644 --- a/NorthwindCRUD/ControllersGraphQL/CustomerController.cs +++ b/NorthwindCRUD/ControllersGraphQL/CustomerController.cs @@ -1,13 +1,13 @@ -namespace NorthwindCRUD.Controllers -{ - using AutoMapper; - using GraphQL.AspNet.Attributes; - using GraphQL.AspNet.Controllers; - using NorthwindCRUD.Models.DbModels; - using NorthwindCRUD.Models.Dtos; - using NorthwindCRUD.Models.InputModels; - using NorthwindCRUD.Services; +using AutoMapper; +using GraphQL.AspNet.Attributes; +using GraphQL.AspNet.Controllers; +using NorthwindCRUD.Models.DbModels; +using NorthwindCRUD.Models.Dtos; +using NorthwindCRUD.Models.InputModels; +using NorthwindCRUD.Services; +namespace NorthwindCRUD.Controllers +{ [GraphRoute("customer")] public class CustomerGraphController : GraphController { @@ -30,7 +30,7 @@ public CustomerDto[] GetAll() } [Query] - public CustomerDto GetById(string id) + public CustomerDto? GetById(string id) { var customer = this.customerService.GetById(id); @@ -45,22 +45,21 @@ public CustomerDto GetById(string id) [Mutation] public CustomerDto Create(CustomerDto model) { - var mappedModel = this.mapper.Map(model); var customer = this.customerService.Create(mappedModel); return this.mapper.Map(customer); } [Mutation] - public CustomerDto Update(CustomerDto model) + public CustomerDto? Update(CustomerDto model) { var mappedModel = this.mapper.Map(model); var customer = this.customerService.Update(mappedModel); - return this.mapper.Map(customer); + return customer != null ? this.mapper.Map(customer) : null; } [Mutation] - public CustomerDto Delete(string id) + public CustomerDto? Delete(string id) { var customer = this.customerService.Delete(id); diff --git a/NorthwindCRUD/ControllersGraphQL/EmployeeController.cs b/NorthwindCRUD/ControllersGraphQL/EmployeeController.cs index e41d0e9..f9cead2 100644 --- a/NorthwindCRUD/ControllersGraphQL/EmployeeController.cs +++ b/NorthwindCRUD/ControllersGraphQL/EmployeeController.cs @@ -30,7 +30,7 @@ public EmployeeDto[] GetAll() } [Query] - public EmployeeDto GetById(int id) + public EmployeeDto? GetById(int id) { var employee = this.employeeService.GetById(id); @@ -41,7 +41,7 @@ public EmployeeDto GetById(int id) return null; } - + [Mutation] public EmployeeDto Create(EmployeeDto model) { @@ -51,15 +51,15 @@ public EmployeeDto Create(EmployeeDto model) } [Mutation] - public EmployeeDto Update(EmployeeDto model) + public EmployeeDto? Update(EmployeeDto model) { var mappedModel = this.mapper.Map(model); var employee = this.employeeService.Update(mappedModel); - return this.mapper.Map(employee); + return employee != null ? this.mapper.Map(employee) : null; } [Mutation] - public EmployeeDto Delete(int id) + public EmployeeDto? Delete(int id) { var employee = this.employeeService.Delete(id); diff --git a/NorthwindCRUD/ControllersGraphQL/OrderController.cs b/NorthwindCRUD/ControllersGraphQL/OrderController.cs index a4e4278..06eda20 100644 --- a/NorthwindCRUD/ControllersGraphQL/OrderController.cs +++ b/NorthwindCRUD/ControllersGraphQL/OrderController.cs @@ -1,13 +1,12 @@ -namespace NorthwindCRUD.Controllers -{ - using AutoMapper; - using GraphQL.AspNet.Attributes; - using GraphQL.AspNet.Controllers; - using NorthwindCRUD.Models.DbModels; - using NorthwindCRUD.Models.Dtos; - using NorthwindCRUD.Models.InputModels; - using NorthwindCRUD.Services; +using AutoMapper; +using GraphQL.AspNet.Attributes; +using GraphQL.AspNet.Controllers; +using NorthwindCRUD.Models.DbModels; +using NorthwindCRUD.Models.Dtos; +using NorthwindCRUD.Services; +namespace NorthwindCRUD.Controllers +{ [GraphRoute("order")] public class OrderGraphController : GraphController { @@ -28,9 +27,9 @@ public OrderDto[] GetAll() var orders = this.orderService.GetAll(); return this.mapper.Map(orders); } - + [Query] - public OrderDto GetById(int id) + public OrderDto? GetById(int id) { var order = this.orderService.GetById(id); @@ -51,15 +50,15 @@ public OrderDto Create(OrderDto model) } [Mutation] - public OrderDto Update(OrderDto model) + public OrderDto? Update(OrderDto model) { var mappedModel = this.mapper.Map(model); var order = this.orderService.Update(mappedModel); - return this.mapper.Map(order); + return order != null ? this.mapper.Map(order) : null; } [Mutation] - public OrderDto Delete(int id) + public OrderDto? Delete(int id) { var order = this.orderService.Delete(id); diff --git a/NorthwindCRUD/DataContext.cs b/NorthwindCRUD/DataContext.cs index 91305b1..72ab415 100644 --- a/NorthwindCRUD/DataContext.cs +++ b/NorthwindCRUD/DataContext.cs @@ -3,27 +3,37 @@ using Microsoft.EntityFrameworkCore; using NorthwindCRUD.Models.DbModels; - public class DataContext : DbContext + public class DataContext : DbContext { - protected readonly IConfiguration Configuration; - - public DataContext(DbContextOptions options) : base(options) + public DataContext(DbContextOptions options) + : base(options) { - } public DbSet Addresses { get; set; } + public DbSet Categories { get; set; } + public DbSet Customers { get; set; } + public DbSet Employees { get; set; } + public DbSet Orders { get; set; } + public DbSet OrderDetails { get; set; } + public DbSet Users { get; set; } + public DbSet Products { get; set; } + public DbSet Regions { get; set; } + public DbSet Shippers { get; set; } + public DbSet Suppliers { get; set; } + public DbSet Territories { get; set; } + public DbSet EmployeesTerritories { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) @@ -88,7 +98,6 @@ protected override void OnModelCreating(ModelBuilder modelBuilder) .WithMany(t => t.EmployeesTerritories); //Composite Keys - modelBuilder.Entity() .HasKey(et => new { et.EmployeeId, et.TerritoryId }); diff --git a/NorthwindCRUD/Filters/AuthResponseOperationFilter.cs b/NorthwindCRUD/Filters/AuthResponseOperationFilter.cs index 6561541..1e4c2b5 100644 --- a/NorthwindCRUD/Filters/AuthResponseOperationFilter.cs +++ b/NorthwindCRUD/Filters/AuthResponseOperationFilter.cs @@ -8,26 +8,27 @@ public class AuthResponsesOperationFilter : IOperationFilter { public void Apply(OpenApiOperation operation, OperationFilterContext context) { - var authAttributes = context.MethodInfo.DeclaringType.GetCustomAttributes(true) + var authAttributes = context.MethodInfo?.DeclaringType?.GetCustomAttributes(true) .Union(context.MethodInfo.GetCustomAttributes(true)) .OfType(); - if (authAttributes.Any()) + if (authAttributes != null && authAttributes.Any()) { var securityRequirement = new OpenApiSecurityRequirement() - { { - new OpenApiSecurityScheme { - Reference = new OpenApiReference + new OpenApiSecurityScheme { - Type = ReferenceType.SecurityScheme, - Id = "Bearer" - } + Reference = new OpenApiReference + { + Type = ReferenceType.SecurityScheme, + Id = "Bearer", + }, + }, + new List() }, - new List() - } - }; + }; + operation.Security = new List { securityRequirement }; operation.Responses.Add("401", new OpenApiResponse { Description = "Unauthorized" }); } diff --git a/NorthwindCRUD/Helpers/DBSeeder.cs b/NorthwindCRUD/Helpers/DBSeeder.cs index 3cf4486..435aac1 100644 --- a/NorthwindCRUD/Helpers/DBSeeder.cs +++ b/NorthwindCRUD/Helpers/DBSeeder.cs @@ -17,9 +17,9 @@ public static void Seed(DataContext dbContext) SeedCategories(dbContext); SeedRegions(dbContext); SeedTerritories(dbContext); - SeedSuppliers(dbContext); + SeedSuppliers(dbContext); SeedProducts(dbContext); - SeedShippers(dbContext); + SeedShippers(dbContext); SeedEmployees(dbContext); SeedCustomers(dbContext); SeedOrders(dbContext); @@ -28,7 +28,7 @@ public static void Seed(DataContext dbContext) transaction.Commit(); } - catch (Exception error) + catch (Exception) { transaction.Rollback(); throw; @@ -42,8 +42,11 @@ private static void SeedEmployeesTerritories(DataContext dbContext) var employeesTerritoriesData = File.ReadAllText("./Resources/employees-territories.json"); var parsedEmployeesTerritories = JsonConvert.DeserializeObject(employeesTerritoriesData); - dbContext.EmployeesTerritories.AddRange(parsedEmployeesTerritories); - dbContext.SaveChanges(); + if (parsedEmployeesTerritories != null) + { + dbContext.EmployeesTerritories.AddRange(parsedEmployeesTerritories); + dbContext.SaveChanges(); + } } } @@ -54,15 +57,18 @@ private static void SeedSuppliers(DataContext dbContext) var suppliersData = File.ReadAllText("./Resources/suppliers.json"); var parsedSuppliers = JsonConvert.DeserializeObject(suppliersData); - foreach (var supplier in parsedSuppliers) + if (parsedSuppliers != null) { - var matchingProducts = dbContext.Products.Where(p => p.SupplierId == supplier.SupplierId).ToList(); - supplier.Products = matchingProducts; + foreach (var supplier in parsedSuppliers) + { + var matchingProducts = dbContext.Products.Where(p => p.SupplierId == supplier.SupplierId).ToList(); + supplier.Products = matchingProducts; - dbContext.Suppliers.Add(supplier); - } + dbContext.Suppliers.Add(supplier); + } - dbContext.SaveChanges(); + dbContext.SaveChanges(); + } } } @@ -72,12 +78,15 @@ private static void SeedShippers(DataContext dbContext) { var shippersData = File.ReadAllText("./Resources/shippers.json"); var parsedShippers = JsonConvert.DeserializeObject(shippersData); - foreach (var shipper in parsedShippers) + if (parsedShippers != null) { - var matchingOrders = dbContext.Orders.Where(o => o.ShipperId == shipper.ShipperId).ToList(); - shipper.Orders = matchingOrders; + foreach (var shipper in parsedShippers) + { + var matchingOrders = dbContext.Orders.Where(o => o.ShipperId == shipper.ShipperId).ToList(); + shipper.Orders = matchingOrders; - dbContext.Shippers.Add(shipper); + dbContext.Shippers.Add(shipper); + } } dbContext.SaveChanges(); @@ -91,8 +100,11 @@ private static void SeedTerritories(DataContext dbContext) var territoriesData = File.ReadAllText("./Resources/territories.json"); var parsedTerritories = JsonConvert.DeserializeObject(territoriesData); - dbContext.Territories.AddRange(parsedTerritories); - dbContext.SaveChanges(); + if (parsedTerritories != null) + { + dbContext.Territories.AddRange(parsedTerritories); + dbContext.SaveChanges(); + } } } @@ -103,17 +115,23 @@ private static void SeedOrders(DataContext dbContext) var ordersData = File.ReadAllText("./Resources/orders.json"); var parsedOrders = JsonConvert.DeserializeObject(ordersData); - foreach (var order in parsedOrders) + if (parsedOrders != null) { - if (dbContext.Addresses.FirstOrDefault(a => a.Street == order.ShipAddress.Street) == null) + foreach (var order in parsedOrders) { - dbContext.Addresses.Add(order.ShipAddress); - } + if (order.ShipAddress != null) + { + if (dbContext.Addresses.FirstOrDefault(a => a.Street == order.ShipAddress.Street) == null) + { + dbContext.Addresses.Add(order.ShipAddress); + } + dbContext.Orders.Add(order); + } + } - dbContext.Orders.Add(order); + dbContext.SaveChanges(); } - dbContext.SaveChanges(); } } @@ -123,8 +141,11 @@ private static void SeedOrderDetails(DataContext dbContext) { var ordersDetailsData = File.ReadAllText("./Resources/orderDetails.json"); var parsedordersDetails = JsonConvert.DeserializeObject(ordersDetailsData); - dbContext.OrderDetails.AddRange(parsedordersDetails); - dbContext.SaveChanges(); + if (parsedordersDetails != null) + { + dbContext.OrderDetails.AddRange(parsedordersDetails); + dbContext.SaveChanges(); + } } } @@ -134,16 +155,20 @@ private static void SeedEmployees(DataContext dbContext) { var employeesData = File.ReadAllText("./Resources/employees.json"); var parsedEmployees = JsonConvert.DeserializeObject(employeesData); - - foreach (var employee in parsedEmployees) + if (parsedEmployees != null) { - if (dbContext.Addresses.FirstOrDefault(a => a.Street == employee.Address.Street) == null) + foreach (var employee in parsedEmployees) { - dbContext.Addresses.Add(employee.Address); + if (dbContext.Addresses.FirstOrDefault(a => a.Street == employee.Address.Street) == null) + { + dbContext.Addresses.Add(employee.Address); + } + + dbContext.Employees.Add(employee); } - dbContext.Employees.Add(employee); + + dbContext.SaveChanges(); } - dbContext.SaveChanges(); } } @@ -154,21 +179,25 @@ private static void SeedCustomers(DataContext dbContext) var customersData = File.ReadAllText("./Resources/customers.json"); var parsedCustomers = JsonConvert.DeserializeObject(customersData); - foreach (var customer in parsedCustomers) + if (parsedCustomers != null) { - var existingCustomer = dbContext.Customers.Find(customer.CustomerId); - - if (existingCustomer == null) + foreach (var customer in parsedCustomers) { - if (dbContext.Addresses.FirstOrDefault(a => a.Street == customer.Address.Street) == null) + var existingCustomer = dbContext.Customers.Find(customer.CustomerId); + + if (existingCustomer == null) { - dbContext.Addresses.Add(customer.Address); - } + if (dbContext.Addresses.FirstOrDefault(a => a.Street == customer.Address.Street) == null) + { + dbContext.Addresses.Add(customer.Address); + } - dbContext.Customers.Add(customer); + dbContext.Customers.Add(customer); + } } + + dbContext.SaveChanges(); } - dbContext.SaveChanges(); } } @@ -179,27 +208,33 @@ private static void SeedProducts(DataContext dbContext) var productsData = File.ReadAllText("./Resources/products.json"); var parsedProducts = JsonConvert.DeserializeObject(productsData); - dbContext.Products.AddRange(parsedProducts); - dbContext.SaveChanges(); + if (parsedProducts != null) + { + dbContext.Products.AddRange(parsedProducts); + dbContext.SaveChanges(); + } } } private static void SeedRegions(DataContext dbContext) - { + { if (!dbContext.Regions.Any()) { var productsData = File.ReadAllText("./Resources/regions.json"); var parsedRegions = JsonConvert.DeserializeObject(productsData); - - foreach (var region in parsedRegions) + if (parsedRegions != null) { - var matchingTerritories = dbContext.Territories.Where(t => t.RegionId == region.RegionId).ToList(); - region.Territories = matchingTerritories; + foreach (var region in parsedRegions) + { + var matchingTerritories = dbContext.Territories.Where(t => t.RegionId == region.RegionId).ToList(); + region.Territories = matchingTerritories; - dbContext.Regions.Add(region); + dbContext.Regions.Add(region); + } + + dbContext.SaveChanges(); } - dbContext.SaveChanges(); } } @@ -210,8 +245,11 @@ private static void SeedCategories(DataContext dbContext) var categoriesData = File.ReadAllText("./Resources/categories.json"); var parsedCategories = JsonConvert.DeserializeObject(categoriesData); - dbContext.Categories.AddRange(parsedCategories); - dbContext.SaveChanges(); + if (parsedCategories != null) + { + dbContext.Categories.AddRange(parsedCategories); + dbContext.SaveChanges(); + } } } } diff --git a/NorthwindCRUD/Helpers/IdGenerator.cs b/NorthwindCRUD/Helpers/IdGenerator.cs index 68fa0c5..9131e47 100644 --- a/NorthwindCRUD/Helpers/IdGenerator.cs +++ b/NorthwindCRUD/Helpers/IdGenerator.cs @@ -9,6 +9,7 @@ public static string CreateLetterId(int length) return new string(Enumerable.Repeat(chars, length) .Select(s => s[random.Next(s.Length)]).ToArray()); } + public static int CreateDigitsId() { Random r = new Random(); diff --git a/NorthwindCRUD/Helpers/PropertyHelper.cs b/NorthwindCRUD/Helpers/PropertyHelper.cs index eb01bda..e3a0cac 100644 --- a/NorthwindCRUD/Helpers/PropertyHelper.cs +++ b/NorthwindCRUD/Helpers/PropertyHelper.cs @@ -4,17 +4,22 @@ public static class PropertyHelper { + [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1000:Do not declare static members on generic types", Justification = "Need generic type here")] public static void MakePropertiesEmptyIfNull(T model) { if (model != null) { - foreach (PropertyInfo prop in model?.GetType()?.GetProperties()) + var properties = model?.GetType()?.GetProperties(); + if (properties != null) { - var value = prop.GetValue(model); - var type = prop.PropertyType; - if (value == null && type == typeof(string)) + foreach (PropertyInfo prop in properties) { - prop.SetValue(model, ""); + var value = prop.GetValue(model); + var type = prop.PropertyType; + if (value == null && type == typeof(string)) + { + prop.SetValue(model, string.Empty); + } } } } diff --git a/NorthwindCRUD/Migrations/20220908121941_InitialCreate.cs b/NorthwindCRUD/Migrations/20220908121941_InitialCreate.cs index 8203baf..f38787e 100644 --- a/NorthwindCRUD/Migrations/20220908121941_InitialCreate.cs +++ b/NorthwindCRUD/Migrations/20220908121941_InitialCreate.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore.Migrations; +// +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/NorthwindCRUD/Migrations/20220908134815_UpdateOrdersTable.cs b/NorthwindCRUD/Migrations/20220908134815_UpdateOrdersTable.cs index 26c8947..c3caad4 100644 --- a/NorthwindCRUD/Migrations/20220908134815_UpdateOrdersTable.cs +++ b/NorthwindCRUD/Migrations/20220908134815_UpdateOrdersTable.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore.Migrations; +// +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable diff --git a/NorthwindCRUD/Migrations/20221115201007_AddUsersTable.cs b/NorthwindCRUD/Migrations/20221115201007_AddUsersTable.cs index 79e9d00..b028cd2 100644 --- a/NorthwindCRUD/Migrations/20221115201007_AddUsersTable.cs +++ b/NorthwindCRUD/Migrations/20221115201007_AddUsersTable.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore.Migrations; +// +using Microsoft.EntityFrameworkCore.Migrations; #nullable disable @@ -22,7 +23,7 @@ protected override void Up(MigrationBuilder migrationBuilder) { UserId = table.Column(type: "nvarchar(450)", nullable: false), Email = table.Column(type: "nvarchar(max)", nullable: false), - Password = table.Column(type: "nvarchar(max)", nullable: false) + Password = table.Column(type: "nvarchar(max)", nullable: false), }, constraints: table => { diff --git a/NorthwindCRUD/Models/Contracts/ICategory.cs b/NorthwindCRUD/Models/Contracts/ICategory.cs index ee0eb61..0826e3d 100644 --- a/NorthwindCRUD/Models/Contracts/ICategory.cs +++ b/NorthwindCRUD/Models/Contracts/ICategory.cs @@ -3,7 +3,7 @@ public interface ICategory { int CategoryId { get; set; } - + string Description { get; set; } string Name { get; set; } diff --git a/NorthwindCRUD/Models/Contracts/ICustomer.cs b/NorthwindCRUD/Models/Contracts/ICustomer.cs index 3f05c49..a8c976d 100644 --- a/NorthwindCRUD/Models/Contracts/ICustomer.cs +++ b/NorthwindCRUD/Models/Contracts/ICustomer.cs @@ -6,7 +6,7 @@ public interface ICustomer { string CustomerId { get; set; } - string CompanyName { get; set; } + string? CompanyName { get; set; } string ContactName { get; set; } diff --git a/NorthwindCRUD/Models/Contracts/IProduct.cs b/NorthwindCRUD/Models/Contracts/IProduct.cs index 072cbc8..e52832d 100644 --- a/NorthwindCRUD/Models/Contracts/IProduct.cs +++ b/NorthwindCRUD/Models/Contracts/IProduct.cs @@ -8,7 +8,7 @@ public interface IProduct int? CategoryId { get; set; } - string QuantityPerUnit { get; set; } + string? QuantityPerUnit { get; set; } double? UnitPrice { get; set; } diff --git a/NorthwindCRUD/Models/Contracts/ISupplier.cs b/NorthwindCRUD/Models/Contracts/ISupplier.cs index e67ee79..264a424 100644 --- a/NorthwindCRUD/Models/Contracts/ISupplier.cs +++ b/NorthwindCRUD/Models/Contracts/ISupplier.cs @@ -4,26 +4,26 @@ public interface ISupplier { int SupplierId { get; set; } - string CompanyName { get; set; } + string? CompanyName { get; set; } - string ContactName { get; set; } + string? ContactName { get; set; } - string ContactTitle { get; set; } + string? ContactTitle { get; set; } - string Address { get; set; } + string? Address { get; set; } - string City { get; set; } + string? City { get; set; } - string Region { get; set; } + string? Region { get; set; } - string PostalCode { get; set; } + string? PostalCode { get; set; } - string Country { get; set; } + string? Country { get; set; } - string Phone { get; set; } + string? Phone { get; set; } - string Fax { get; set; } + string? Fax { get; set; } - string HomePage { get; set; } + string? HomePage { get; set; } } } diff --git a/NorthwindCRUD/Models/Contracts/IUser.cs b/NorthwindCRUD/Models/Contracts/IUser.cs index 46f0e81..42102d8 100644 --- a/NorthwindCRUD/Models/Contracts/IUser.cs +++ b/NorthwindCRUD/Models/Contracts/IUser.cs @@ -1,6 +1,6 @@ namespace NorthwindCRUD.Models.Contracts { - public class IUser + public interface IUser { string Email { get; set; } diff --git a/NorthwindCRUD/Models/DbModels/AddressDb.cs b/NorthwindCRUD/Models/DbModels/AddressDb.cs index 77ad1cd..527ebb9 100644 --- a/NorthwindCRUD/Models/DbModels/AddressDb.cs +++ b/NorthwindCRUD/Models/DbModels/AddressDb.cs @@ -1,9 +1,9 @@ -namespace NorthwindCRUD.Models.DbModels -{ - using NorthwindCRUD.Models.Contracts; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using NorthwindCRUD.Models.Contracts; +namespace NorthwindCRUD.Models.DbModels +{ public class AddressDb : IAddress { [Key] @@ -27,6 +27,5 @@ public class AddressDb : IAddress public ICollection Employees { get; set; } public ICollection Orders { get; set; } - } } diff --git a/NorthwindCRUD/Models/DbModels/CategoryDb.cs b/NorthwindCRUD/Models/DbModels/CategoryDb.cs index 11b0ec0..14c737a 100644 --- a/NorthwindCRUD/Models/DbModels/CategoryDb.cs +++ b/NorthwindCRUD/Models/DbModels/CategoryDb.cs @@ -1,9 +1,9 @@ -namespace NorthwindCRUD.Models.DbModels -{ - using NorthwindCRUD.Models.Contracts; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using NorthwindCRUD.Models.Contracts; +namespace NorthwindCRUD.Models.DbModels +{ public class CategoryDb : ICategory, ICategoryDetail { [Key] diff --git a/NorthwindCRUD/Models/DbModels/CustomerDb.cs b/NorthwindCRUD/Models/DbModels/CustomerDb.cs index 8ab315d..da3685f 100644 --- a/NorthwindCRUD/Models/DbModels/CustomerDb.cs +++ b/NorthwindCRUD/Models/DbModels/CustomerDb.cs @@ -1,9 +1,9 @@ -namespace NorthwindCRUD.Models.DbModels -{ - using NorthwindCRUD.Models.Contracts; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using NorthwindCRUD.Models.Contracts; +namespace NorthwindCRUD.Models.DbModels +{ public class CustomerDb : ICustomer { [Key] diff --git a/NorthwindCRUD/Models/DbModels/EmployeeDb.cs b/NorthwindCRUD/Models/DbModels/EmployeeDb.cs index c0bad25..431e40a 100644 --- a/NorthwindCRUD/Models/DbModels/EmployeeDb.cs +++ b/NorthwindCRUD/Models/DbModels/EmployeeDb.cs @@ -1,9 +1,9 @@ -namespace NorthwindCRUD.Models.DbModels -{ - using NorthwindCRUD.Models.Contracts; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using NorthwindCRUD.Models.Contracts; +namespace NorthwindCRUD.Models.DbModels +{ public class EmployeeDb : IEmployee { [Key] @@ -32,7 +32,7 @@ public class EmployeeDb : IEmployee public int ReportsTo { get; set; } - public ICollection EmployeesTerritories { get; set; } = new List(); + public ICollection EmployeesTerritories { get; set; } = new List(); public ICollection Orders { get; set; } = new List(); } diff --git a/NorthwindCRUD/Models/DbModels/OrderDb.cs b/NorthwindCRUD/Models/DbModels/OrderDb.cs index fa0f7c2..ccf9003 100644 --- a/NorthwindCRUD/Models/DbModels/OrderDb.cs +++ b/NorthwindCRUD/Models/DbModels/OrderDb.cs @@ -1,9 +1,8 @@ -namespace NorthwindCRUD.Models.DbModels -{ - using NorthwindCRUD.Models.Contracts; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +namespace NorthwindCRUD.Models.DbModels +{ public class OrderDb { public OrderDb() @@ -16,7 +15,7 @@ public OrderDb() public string? CustomerId { get; set; } - public CustomerDb? Customer { get; set;} + public CustomerDb? Customer { get; set; } public int? EmployeeId { get; set; } diff --git a/NorthwindCRUD/Models/DbModels/ProductDb.cs b/NorthwindCRUD/Models/DbModels/ProductDb.cs index e859370..4c32449 100644 --- a/NorthwindCRUD/Models/DbModels/ProductDb.cs +++ b/NorthwindCRUD/Models/DbModels/ProductDb.cs @@ -1,6 +1,6 @@ -using NorthwindCRUD.Models.Contracts; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using NorthwindCRUD.Models.Contracts; namespace NorthwindCRUD.Models.DbModels { @@ -18,7 +18,7 @@ public class ProductDb : IProduct public CategoryDb? Category { get; set; } - public string QuantityPerUnit { get; set; } + public string? QuantityPerUnit { get; set; } public double? UnitPrice { get; set; } diff --git a/NorthwindCRUD/Models/DbModels/RegionDb.cs b/NorthwindCRUD/Models/DbModels/RegionDb.cs index adc3d22..241ef12 100644 --- a/NorthwindCRUD/Models/DbModels/RegionDb.cs +++ b/NorthwindCRUD/Models/DbModels/RegionDb.cs @@ -1,6 +1,6 @@ -using NorthwindCRUD.Models.Contracts; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using NorthwindCRUD.Models.Contracts; namespace NorthwindCRUD.Models.DbModels { diff --git a/NorthwindCRUD/Models/DbModels/ShipperDb.cs b/NorthwindCRUD/Models/DbModels/ShipperDb.cs index 389f211..583a785 100644 --- a/NorthwindCRUD/Models/DbModels/ShipperDb.cs +++ b/NorthwindCRUD/Models/DbModels/ShipperDb.cs @@ -1,6 +1,6 @@ -using NorthwindCRUD.Models.Contracts; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using NorthwindCRUD.Models.Contracts; namespace NorthwindCRUD.Models.DbModels { diff --git a/NorthwindCRUD/Models/DbModels/SupplierDb.cs b/NorthwindCRUD/Models/DbModels/SupplierDb.cs index 11716d1..08cf742 100644 --- a/NorthwindCRUD/Models/DbModels/SupplierDb.cs +++ b/NorthwindCRUD/Models/DbModels/SupplierDb.cs @@ -1,6 +1,6 @@ -using NorthwindCRUD.Models.Contracts; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using NorthwindCRUD.Models.Contracts; namespace NorthwindCRUD.Models.DbModels { diff --git a/NorthwindCRUD/Models/DbModels/TerritoryDb.cs b/NorthwindCRUD/Models/DbModels/TerritoryDb.cs index 2eedd46..ced7c21 100644 --- a/NorthwindCRUD/Models/DbModels/TerritoryDb.cs +++ b/NorthwindCRUD/Models/DbModels/TerritoryDb.cs @@ -1,6 +1,6 @@ -using NorthwindCRUD.Models.Contracts; -using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; using System.ComponentModel.DataAnnotations.Schema; +using NorthwindCRUD.Models.Contracts; namespace NorthwindCRUD.Models.DbModels { diff --git a/NorthwindCRUD/Models/DbModels/UserDb.cs b/NorthwindCRUD/Models/DbModels/UserDb.cs index 2fec3c1..091b662 100644 --- a/NorthwindCRUD/Models/DbModels/UserDb.cs +++ b/NorthwindCRUD/Models/DbModels/UserDb.cs @@ -1,9 +1,9 @@ -namespace NorthwindCRUD.Models.DbModels -{ - using NorthwindCRUD.Models.Contracts; - using System.ComponentModel.DataAnnotations; - using System.ComponentModel.DataAnnotations.Schema; +using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; +using NorthwindCRUD.Models.Contracts; +namespace NorthwindCRUD.Models.DbModels +{ public class UserDb : IUser { [Key] @@ -14,5 +14,4 @@ public class UserDb : IUser public string Password { get; set; } } -} - \ No newline at end of file +} \ No newline at end of file diff --git a/NorthwindCRUD/Models/Dtos/AddressDto.cs b/NorthwindCRUD/Models/Dtos/AddressDto.cs index 013a1fe..d117a5d 100644 --- a/NorthwindCRUD/Models/Dtos/AddressDto.cs +++ b/NorthwindCRUD/Models/Dtos/AddressDto.cs @@ -4,16 +4,16 @@ public class AddressDto : IAddress { - public string Street {get; set;} + public string Street { get; set; } public string City { get; set; } - public string Region {get; set;} + public string Region { get; set; } public string PostalCode { get; set; } public string Country { get; set; } - public string Phone { get; set; } + public string? Phone { get; set; } } } diff --git a/NorthwindCRUD/Models/Dtos/CustomerDto.cs b/NorthwindCRUD/Models/Dtos/CustomerDto.cs index 0faa63c..357602e 100644 --- a/NorthwindCRUD/Models/Dtos/CustomerDto.cs +++ b/NorthwindCRUD/Models/Dtos/CustomerDto.cs @@ -1,14 +1,14 @@ -namespace NorthwindCRUD.Models.Dtos -{ - using NorthwindCRUD.Models.Contracts; - using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; +using NorthwindCRUD.Models.Contracts; +namespace NorthwindCRUD.Models.Dtos +{ public class CustomerDto : ICustomer { public string CustomerId { get; set; } [Required] - public string CompanyName { get; set; } + public string? CompanyName { get; set; } public string ContactName { get; set; } diff --git a/NorthwindCRUD/Models/Dtos/EmployeeDto.cs b/NorthwindCRUD/Models/Dtos/EmployeeDto.cs index 3925ec9..0a231b0 100644 --- a/NorthwindCRUD/Models/Dtos/EmployeeDto.cs +++ b/NorthwindCRUD/Models/Dtos/EmployeeDto.cs @@ -1,9 +1,9 @@ -namespace NorthwindCRUD.Models.Dtos -{ - using NorthwindCRUD.Models.Contracts; - using Swashbuckle.AspNetCore.Annotations; - using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; +using NorthwindCRUD.Models.Contracts; +using Swashbuckle.AspNetCore.Annotations; +namespace NorthwindCRUD.Models.Dtos +{ public class EmployeeDto : IEmployee { [SwaggerSchema("Number automatically assigned to new employee.")] @@ -20,7 +20,7 @@ public class EmployeeDto : IEmployee [SwaggerSchema("Employee's title")] public string Title { get; set; } - [SwaggerSchema("Title used in salutations")] + [SwaggerSchema("Title used in salutations")] public string TitleOfCourtesy { get; set; } [SwaggerSchema("Employee's birth date", Format = "date")] @@ -32,7 +32,7 @@ public class EmployeeDto : IEmployee public string AddressId { get; set; } public AddressDto Address { get; set; } - + [SwaggerSchema("General information about employee's background.")] public string Notes { get; set; } diff --git a/NorthwindCRUD/Models/Dtos/EmployeeTerritoryDto.cs b/NorthwindCRUD/Models/Dtos/EmployeeTerritoryDto.cs index da2a940..1bab623 100644 --- a/NorthwindCRUD/Models/Dtos/EmployeeTerritoryDto.cs +++ b/NorthwindCRUD/Models/Dtos/EmployeeTerritoryDto.cs @@ -1,8 +1,7 @@ +using NorthwindCRUD.Models.Contracts; + namespace NorthwindCRUD.Models.Dtos { - using NorthwindCRUD.Models.Contracts; - using System.ComponentModel.DataAnnotations; - public class EmployeeTerritoryDto : IEmployeeTerritory { public int EmployeeId { get; set; } diff --git a/NorthwindCRUD/Models/Dtos/LoginDto.cs b/NorthwindCRUD/Models/Dtos/LoginDto.cs index c050e57..f3f8648 100644 --- a/NorthwindCRUD/Models/Dtos/LoginDto.cs +++ b/NorthwindCRUD/Models/Dtos/LoginDto.cs @@ -1,8 +1,8 @@ -namespace NorthwindCRUD.Models.Dtos -{ - using NorthwindCRUD.Models.Contracts; - using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; +using NorthwindCRUD.Models.Contracts; +namespace NorthwindCRUD.Models.Dtos +{ public class LoginDto : IUser { [EmailAddress] diff --git a/NorthwindCRUD/Models/Dtos/RegisterDto.cs b/NorthwindCRUD/Models/Dtos/RegisterDto.cs index 0417faf..a17d7c5 100644 --- a/NorthwindCRUD/Models/Dtos/RegisterDto.cs +++ b/NorthwindCRUD/Models/Dtos/RegisterDto.cs @@ -1,8 +1,8 @@ -namespace NorthwindCRUD.Models.Dtos -{ - using NorthwindCRUD.Models.Contracts; - using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations; +using NorthwindCRUD.Models.Contracts; +namespace NorthwindCRUD.Models.Dtos +{ public class RegisterDto : IUser { [Required] diff --git a/NorthwindCRUD/Models/Dtos/SalesDto.cs b/NorthwindCRUD/Models/Dtos/SalesDto.cs index a2b0147..4ee1096 100644 --- a/NorthwindCRUD/Models/Dtos/SalesDto.cs +++ b/NorthwindCRUD/Models/Dtos/SalesDto.cs @@ -3,7 +3,9 @@ public class SalesDto { public int ProductId { get; set; } + public int QuantitySold { get; set; } + public double SaleAmount { get; set; } } } diff --git a/NorthwindCRUD/Models/Dtos/SupplierDto.cs b/NorthwindCRUD/Models/Dtos/SupplierDto.cs index e659ead..48c8913 100644 --- a/NorthwindCRUD/Models/Dtos/SupplierDto.cs +++ b/NorthwindCRUD/Models/Dtos/SupplierDto.cs @@ -6,26 +6,26 @@ public class SupplierDto : ISupplier { public int SupplierId { get; set; } - public string CompanyName { get; set; } + public string? CompanyName { get; set; } - public string ContactName { get; set; } + public string? ContactName { get; set; } - public string ContactTitle { get; set; } + public string? ContactTitle { get; set; } - public string Address { get; set; } + public string? Address { get; set; } - public string City { get; set; } + public string? City { get; set; } - public string Region { get; set; } + public string? Region { get; set; } - public string PostalCode { get; set; } + public string? PostalCode { get; set; } - public string Country { get; set; } + public string? Country { get; set; } - public string Phone { get; set; } + public string? Phone { get; set; } - public string Fax { get; set; } + public string? Fax { get; set; } - public string HomePage { get; set; } + public string? HomePage { get; set; } } } diff --git a/NorthwindCRUD/NorthwindCRUD.csproj b/NorthwindCRUD/NorthwindCRUD.csproj index 9cb16fa..faf2e0a 100644 --- a/NorthwindCRUD/NorthwindCRUD.csproj +++ b/NorthwindCRUD/NorthwindCRUD.csproj @@ -1,33 +1,50 @@  - - net6.0 - enable - enable - - - - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - + + net6.0 + enable + enable + + ../NorthwindCRUD.ruleset + 6.0-recommended + + + + true + + 1701;1702;CS8618 + + + + 1701;1702;CS8618 + + + + + + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + diff --git a/NorthwindCRUD/Program.cs b/NorthwindCRUD/Program.cs index 336509f..5cd91cb 100644 --- a/NorthwindCRUD/Program.cs +++ b/NorthwindCRUD/Program.cs @@ -1,169 +1,183 @@ -using AutoMapper; -using Microsoft.AspNetCore.Authentication.JwtBearer; +using System.Text; +using AutoMapper; using GraphQL.AspNet.Configuration.Mvc; +using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.AspNetCore.Mvc; +using Microsoft.Data.Sqlite; using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Diagnostics; using Microsoft.IdentityModel.Tokens; using Microsoft.OpenApi.Models; -using Microsoft.EntityFrameworkCore.Diagnostics; -using NorthwindCRUD; +using NorthwindCRUD.Filters; using NorthwindCRUD.Helpers; using NorthwindCRUD.Services; -using System.Text; -using NorthwindCRUD.Filters; -using Microsoft.Data.Sqlite; -using Microsoft.Extensions.Options; -var builder = WebApplication.CreateBuilder(args); -var AllowAnyOriginPolicy = "_allowAnyOrigin"; +namespace NorthwindCRUD +{ + public class Program + { + public static void Main(string[] args) + { + var builder = WebApplication.CreateBuilder(args); -builder.Logging.ClearProviders(); -builder.Logging.AddConsole(); + var allowAnyOriginPolicy = "_allowAnyOrigin"; -builder.Services.AddControllers(options => - options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true) - .AddNewtonsoftJson(options => - options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore - ); + builder.Logging.ClearProviders(); + builder.Logging.AddConsole(); -builder.Services.AddEndpointsApiExplorer(); -builder.Services.AddSwaggerGen(option => -{ - option.SwaggerDoc("v1", new OpenApiInfo { Title = "Northwind CRUD", Version = "v1" }); - option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme - { - In = ParameterLocation.Header, - Description = "Please enter a valid token", - Name = "Authorization", - Type = SecuritySchemeType.Http, - BearerFormat = "JWT", - Scheme = "bearer" - }); - - option.OperationFilter(); - option.EnableAnnotations(); -}); - -builder.Services.AddCors(options => -{ - options.AddPolicy(name: AllowAnyOriginPolicy, - policy => + builder.Services.AddControllers(options => + options.SuppressImplicitRequiredAttributeForNonNullableReferenceTypes = true) + .AddNewtonsoftJson(options => + options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore); + + builder.Services.AddEndpointsApiExplorer(); + + builder.Services.AddSwaggerGen(option => + { + option.SwaggerDoc("v1", new OpenApiInfo { Title = "Northwind CRUD", Version = "v1" }); + option.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme + { + In = ParameterLocation.Header, + Description = "Please enter a valid token", + Name = "Authorization", + Type = SecuritySchemeType.Http, + BearerFormat = "JWT", + Scheme = "bearer", + }); + + option.OperationFilter(); + option.EnableAnnotations(); + }); + + builder.Services.AddCors(options => + { + options.AddPolicy( + name: allowAnyOriginPolicy, + policy => + { + policy.AllowAnyOrigin() + .AllowAnyHeader() + .AllowAnyMethod(); + }); + }); + + var dbProvider = builder.Configuration.GetConnectionString("Provider"); + + if (dbProvider == "SQLite") + { + // For SQLite in memory to be shared across multiple EF calls, we need to maintain a separate open connection. + // see post https://stackoverflow.com/questions/56319638/entityframeworkcore-sqlite-in-memory-db-tables-are-not-created + var keepAliveConnection = new SqliteConnection(builder.Configuration.GetConnectionString("SQLiteConnectionString")); + keepAliveConnection.Open(); + } + + builder.Services.AddDbContext(options => + { + if (dbProvider == "SqlServer") + { + options.UseSqlServer(builder.Configuration.GetConnectionString("SqlServerConnectionString")); + } + else if (dbProvider == "InMemory") + { + options.ConfigureWarnings(warnOpts => { - policy.AllowAnyOrigin() - .AllowAnyHeader() - .AllowAnyMethod(); + // InMemory doesn't support transactions and we're ok with it + warnOpts.Ignore(InMemoryEventId.TransactionIgnoredWarning); }); -}); -var dbProvider = builder.Configuration.GetConnectionString("Provider"); -if (dbProvider == "SQLite") -{ - // For SQLite in memory to be shared across multiple EF calls, we need to maintain a separate open connection. - // see post https://stackoverflow.com/questions/56319638/entityframeworkcore-sqlite-in-memory-db-tables-are-not-created - var keepAliveConnection = new SqliteConnection(builder.Configuration.GetConnectionString("SQLiteConnectionString")); - keepAliveConnection.Open(); -} + options.UseInMemoryDatabase(databaseName: builder.Configuration.GetConnectionString("InMemoryDBConnectionString")); + } + else if (dbProvider == "SQLite") + { + options.UseSqlite(builder.Configuration.GetConnectionString("SQLiteConnectionString")); + } + }); +#pragma warning disable ASP0000 // Do not call 'IServiceCollection.BuildServiceProvider' in 'ConfigureServices' + var serviceProvider = builder.Services.BuildServiceProvider(); // TODO: review this warning! +#pragma warning restore ASP0000 // Do not call 'IServiceCollection.BuildServiceProvider' in 'ConfigureServices' -builder.Services.AddDbContext(options => -{ - if (dbProvider == "SqlServer") - { - options.UseSqlServer(builder.Configuration.GetConnectionString("SqlServerConnectionString")); - } - else if (dbProvider == "InMemory") - { - options.ConfigureWarnings(warnOpts => - { - // InMemory doesn't support transactions and we're ok with it - warnOpts.Ignore(InMemoryEventId.TransactionIgnoredWarning); - }); + var logger = serviceProvider.GetRequiredService>(); - options.UseInMemoryDatabase(databaseName: builder.Configuration.GetConnectionString("InMemoryDBConnectionString")); - } - else if (dbProvider == "SQLite") - { - options.UseSqlite(builder.Configuration.GetConnectionString("SQLiteConnectionString")); - } -}); + builder.Services.AddSingleton(typeof(ILogger), logger); -var serviceProvider = builder.Services.BuildServiceProvider(); -var logger = serviceProvider.GetRequiredService>(); -builder.Services.AddSingleton(typeof(ILogger), logger); + var config = new MapperConfiguration(cfg => + { + cfg.AddProfile(new MappingProfiles()); + }); -var config = new MapperConfiguration(cfg => -{ - cfg.AddProfile(new MappingProfiles()); -}); + var mapper = config.CreateMapper(); -var mapper = config.CreateMapper(); -builder.Services.AddSingleton(mapper); + builder.Services.AddSingleton(mapper); -builder.Services.AddAuthentication(options => -{ - options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; - options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; -}).AddJwtBearer(o => -{ - o.TokenValidationParameters = new TokenValidationParameters - { - ValidIssuer = builder.Configuration["Jwt:Issuer"], - ValidAudience = builder.Configuration["Jwt:Audience"], - IssuerSigningKey = new SymmetricSecurityKey - (Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])), - ValidateIssuer = true, - ValidateAudience = true, - ValidateLifetime = false, - ValidateIssuerSigningKey = true - }; -}); -builder.Services.AddAuthorization(); - -builder.Services.AddScoped(); -builder.Services.AddTransient(); -builder.Services.AddTransient(); -builder.Services.AddTransient(); -builder.Services.AddTransient(); -builder.Services.AddTransient(); -builder.Services.AddTransient(); -builder.Services.AddTransient(); -builder.Services.AddTransient(); -builder.Services.AddTransient(); -builder.Services.AddTransient(); -builder.Services.AddTransient(); -builder.Services.AddTransient(); - -var app = builder.Build(); - -// Necessary to detect if it's behind a load balancer, for example changing protocol, port or hostname -app.UseForwardedHeaders(); - -app.UseHttpsRedirection(); -app.UseDefaultFiles(); -app.UseStaticFiles(); - -app.UseRouting(); - -app.UseCors(AllowAnyOriginPolicy); - -app.UseAuthentication(); -app.UseAuthorization(); - -app.UseGraphQL(); - -app.UseSwagger(c => - { - c.PreSerializeFilters.Add((swagger, httpReq) => + builder.Services.AddAuthentication(options => + { + options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme; + options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme; + }).AddJwtBearer(o => { - // Adding server base address in the generated file relative to the server's host - swagger.Servers = new List { new OpenApiServer { Url = $"https://{httpReq.Host.Value}" } }; + o.TokenValidationParameters = new TokenValidationParameters + { + ValidIssuer = builder.Configuration["Jwt:Issuer"], + ValidAudience = builder.Configuration["Jwt:Audience"], + IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"])), + ValidateIssuer = true, + ValidateAudience = true, + ValidateLifetime = false, + ValidateIssuerSigningKey = true, + }; }); - }); -app.UseSwaggerUI(); -app.UseSeedDB(); + builder.Services.AddAuthorization(); + + builder.Services.AddScoped(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + builder.Services.AddTransient(); + + var app = builder.Build(); + + // Necessary to detect if it's behind a load balancer, for example changing protocol, port or hostname + app.UseForwardedHeaders(); + + app.UseHttpsRedirection(); + app.UseDefaultFiles(); + app.UseStaticFiles(); + + app.UseRouting(); -app.MapControllers(); + app.UseCors(allowAnyOriginPolicy); -app.Run(); + app.UseAuthentication(); + app.UseAuthorization(); + + app.UseGraphQL(); + + app.UseSwagger(c => + { + c.PreSerializeFilters.Add((swagger, httpReq) => + { + // Adding server base address in the generated file relative to the server's host + swagger.Servers = new List { new OpenApiServer { Url = $"https://{httpReq.Host.Value}" } }; + }); + }); + + app.UseSwaggerUI(); + app.UseSeedDB(); + + app.MapControllers(); + + app.Run(); + } + } +} diff --git a/NorthwindCRUD/Services/AuthService.cs b/NorthwindCRUD/Services/AuthService.cs index 93b956e..cf1bd57 100644 --- a/NorthwindCRUD/Services/AuthService.cs +++ b/NorthwindCRUD/Services/AuthService.cs @@ -1,12 +1,13 @@ -namespace NorthwindCRUD.Services +using System.IdentityModel.Tokens.Jwt; +using System.Security.Claims; +using System.Text; +using Microsoft.IdentityModel.Tokens; +using NorthwindCRUD.Helpers; +using NorthwindCRUD.Models.DbModels; + +namespace NorthwindCRUD.Services { - using Microsoft.IdentityModel.Tokens; - using System.IdentityModel.Tokens.Jwt; - using System.Security.Claims; - using System.Text; using BCrypt.Net; - using NorthwindCRUD.Helpers; - using NorthwindCRUD.Models.DbModels; public class AuthService { @@ -23,7 +24,7 @@ public AuthService(DataContext dataContext, IConfiguration configuration) public bool IsAuthenticated(string email, string password) { var user = this.GetByEmail(email); - return this.DoesUserExists(email) && BCrypt.Verify(password, user.Password); + return this.DoesUserExists(email) && BCrypt.Verify(password, user?.Password); } public bool DoesUserExists(string email) @@ -32,12 +33,12 @@ public bool DoesUserExists(string email) return user != null; } - public UserDb GetById(string id) + public UserDb? GetById(string id) { return this.dataContext.Users.FirstOrDefault(c => c.UserId == id); } - public UserDb GetByEmail(string email) + public UserDb? GetByEmail(string email) { return this.dataContext.Users.FirstOrDefault(c => c.Email == email); } @@ -51,6 +52,7 @@ public UserDb RegisterUser(UserDb model) id = IdGenerator.CreateLetterId(10); existWithId = this.GetById(id); } + model.UserId = id; model.Password = BCrypt.HashPassword(model.Password); @@ -71,16 +73,15 @@ public string GenerateJwtToken(string email) { Subject = new ClaimsIdentity(new[] { - new Claim("Id", Guid.NewGuid().ToString()), - new Claim(JwtRegisteredClaimNames.Sub, email), - new Claim(JwtRegisteredClaimNames.Email, email), - new Claim(JwtRegisteredClaimNames.Jti, - Guid.NewGuid().ToString()) - }), + new Claim("Id", Guid.NewGuid().ToString()), + new Claim(JwtRegisteredClaimNames.Sub, email), + new Claim(JwtRegisteredClaimNames.Email, email), + new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()), + }), Expires = DateTime.UtcNow.AddMinutes(5), Issuer = issuer, Audience = audience, - SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature) + SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha512Signature), }; var tokenHandler = new JwtSecurityTokenHandler(); var token = tokenHandler.CreateToken(tokenDescriptor); diff --git a/NorthwindCRUD/Services/CategoryService.cs b/NorthwindCRUD/Services/CategoryService.cs index 05056c1..872f84c 100644 --- a/NorthwindCRUD/Services/CategoryService.cs +++ b/NorthwindCRUD/Services/CategoryService.cs @@ -5,7 +5,6 @@ public class CategoryService { - private readonly DataContext dataContext; public CategoryService(DataContext dataContext) @@ -18,7 +17,7 @@ public CategoryDb[] GetAll() return this.dataContext.Categories.ToArray(); } - public CategoryDb GetById(int id) + public CategoryDb? GetById(int id) { return this.dataContext.Categories.FirstOrDefault(c => c.CategoryId == id); } @@ -32,6 +31,7 @@ public CategoryDb Create(CategoryDb model) id = IdGenerator.CreateDigitsId(); existWithId = this.GetById(id); } + model.CategoryId = id; PropertyHelper.MakePropertiesEmptyIfNull(model); @@ -42,7 +42,7 @@ public CategoryDb Create(CategoryDb model) return categoryEntity.Entity; } - public CategoryDb Update(CategoryDb model) + public CategoryDb? Update(CategoryDb model) { var categoryEntity = this.dataContext.Categories.FirstOrDefault(c => c.CategoryId == model.CategoryId); if (categoryEntity != null) @@ -57,7 +57,7 @@ public CategoryDb Update(CategoryDb model) return categoryEntity; } - public CategoryDb Delete(int id) + public CategoryDb? Delete(int id) { var categoryEntity = this.GetById(id); if (categoryEntity != null) diff --git a/NorthwindCRUD/Services/CustomerService.cs b/NorthwindCRUD/Services/CustomerService.cs index f7fc245..e52419b 100644 --- a/NorthwindCRUD/Services/CustomerService.cs +++ b/NorthwindCRUD/Services/CustomerService.cs @@ -1,7 +1,6 @@ using Microsoft.EntityFrameworkCore; using NorthwindCRUD.Helpers; using NorthwindCRUD.Models.DbModels; -using System.Reflection; namespace NorthwindCRUD.Services { @@ -21,7 +20,7 @@ public CustomerDb[] GetAll() .ToArray(); } - public CustomerDb GetById(string id) + public CustomerDb? GetById(string id) { return this.dataContext.Customers .Include(c => c.Address) @@ -37,24 +36,28 @@ public CustomerDb Create(CustomerDb model) id = IdGenerator.CreateLetterId(6); existWithId = this.GetById(id); } + model.CustomerId = id; PropertyHelper.MakePropertiesEmptyIfNull(model); if (model.Address == null) { - var emptyAddress = this.dataContext.Addresses.FirstOrDefault(a => a.Street == ""); - model.Address = emptyAddress; - model.AddressId = emptyAddress.AddressId; + var emptyAddress = this.dataContext.Addresses.FirstOrDefault(a => a.Street == string.Empty); + if (emptyAddress != null) + { + model.Address = emptyAddress; + model.AddressId = emptyAddress.AddressId; + } } var customerEntity = this.dataContext.Customers.Add(model); this.dataContext.SaveChanges(); - + return customerEntity.Entity; } - public CustomerDb Update(CustomerDb model) + public CustomerDb? Update(CustomerDb model) { var customerEntity = this.dataContext.Customers .Include(c => c.Address) @@ -91,7 +94,7 @@ public CustomerDb Update(CustomerDb model) return customerEntity; } - public CustomerDb Delete(string id) + public CustomerDb? Delete(string id) { var customerEntity = this.GetById(id); if (customerEntity != null) diff --git a/NorthwindCRUD/Services/EmployeeService.cs b/NorthwindCRUD/Services/EmployeeService.cs index 28e97b0..8210435 100644 --- a/NorthwindCRUD/Services/EmployeeService.cs +++ b/NorthwindCRUD/Services/EmployeeService.cs @@ -20,7 +20,7 @@ public EmployeeDb[] GetAll() .ToArray(); } - public EmployeeDb GetById(int id) + public EmployeeDb? GetById(int id) { return this.dataContext.Employees.FirstOrDefault(c => c.EmployeeId == id); } @@ -41,15 +41,19 @@ public EmployeeDb Create(EmployeeDb model) id = IdGenerator.CreateDigitsId(); existWithId = this.GetById(id); } + model.EmployeeId = id; PropertyHelper.MakePropertiesEmptyIfNull(model); if (model.Address == null) { - var emptyAddress = this.dataContext.Addresses.FirstOrDefault(a => a.Street == ""); - model.Address = emptyAddress; - model.AddressId = emptyAddress.AddressId; + var emptyAddress = this.dataContext.Addresses.FirstOrDefault(a => a.Street == string.Empty); + if (emptyAddress != null) + { + model.Address = emptyAddress; + model.AddressId = emptyAddress.AddressId; + } } var employeeEntity = this.dataContext.Employees.Add(model); @@ -58,7 +62,7 @@ public EmployeeDb Create(EmployeeDb model) return employeeEntity.Entity; } - public EmployeeDb Update(EmployeeDb model) + public EmployeeDb? Update(EmployeeDb model) { var employeeEntity = this.dataContext.Employees .Include(c => c.Address) @@ -100,7 +104,7 @@ public EmployeeDb Update(EmployeeDb model) return employeeEntity; } - public EmployeeDb Delete(int id) + public EmployeeDb? Delete(int id) { var employeeEntity = this.GetById(id); if (employeeEntity != null) diff --git a/NorthwindCRUD/Services/EmployeeTerritoryService.cs b/NorthwindCRUD/Services/EmployeeTerritoryService.cs index b7f3fae..04135b8 100644 --- a/NorthwindCRUD/Services/EmployeeTerritoryService.cs +++ b/NorthwindCRUD/Services/EmployeeTerritoryService.cs @@ -1,4 +1,5 @@ -using Microsoft.EntityFrameworkCore; +using System.Globalization; +using Microsoft.EntityFrameworkCore; using NorthwindCRUD.Constants; using NorthwindCRUD.Models.DbModels; @@ -13,7 +14,8 @@ public EmployeeTerritoryService(DataContext dataContext) this.dataContext = dataContext; } - public EmployeeDb[] GetEmployeesByTerritoryId(string id) + [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1011:Closing square brackets should be spaced correctly", Justification = "Need to return nullable type")] + public EmployeeDb[]? GetEmployeesByTerritoryId(string id) { var territory = this.dataContext.Territories .Include(t => t.EmployeesTerritories) @@ -28,10 +30,9 @@ public EmployeeDb[] GetEmployeesByTerritoryId(string id) return null; } - - public TerritoryDb[] GetTeritoriesByEmployeeId(int id) + [System.Diagnostics.CodeAnalysis.SuppressMessage("StyleCop.CSharp.SpacingRules", "SA1011:Closing square brackets should be spaced correctly", Justification = "Need to return nullable type")] + public TerritoryDb[]? GetTeritoriesByEmployeeId(int id) { - var employee = this.dataContext.Employees .Include(c => c.Address) .Include(c => c.EmployeesTerritories) @@ -42,6 +43,7 @@ public TerritoryDb[] GetTeritoriesByEmployeeId(int id) { return employee.EmployeesTerritories.Select(et => et.Territory).ToArray(); } + return null; } @@ -49,18 +51,18 @@ public EmployeeTerritoryDb AddTerritoryToEmployee(EmployeeTerritoryDb model) { if (this.dataContext.Employees.FirstOrDefault(e => e.EmployeeId == model.EmployeeId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Employee), model.EmployeeId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Employee), model.EmployeeId.ToString(CultureInfo.InvariantCulture))); } if (this.dataContext.Territories.FirstOrDefault(t => t.TerritoryId == model.TerritoryId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Territory), model.TerritoryId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Territory), model.TerritoryId.ToString())); } var employeeTerritory = new EmployeeTerritoryDb { EmployeeId = model.EmployeeId, - TerritoryId = model.TerritoryId + TerritoryId = model.TerritoryId, }; dataContext.EmployeesTerritories.Add(employeeTerritory); diff --git a/NorthwindCRUD/Services/OrderService.cs b/NorthwindCRUD/Services/OrderService.cs index ebe71f4..2dbb900 100644 --- a/NorthwindCRUD/Services/OrderService.cs +++ b/NorthwindCRUD/Services/OrderService.cs @@ -1,12 +1,12 @@ -namespace NorthwindCRUD.Services +using System.Globalization; +using Microsoft.CodeAnalysis; +using Microsoft.EntityFrameworkCore; +using NorthwindCRUD.Constants; +using NorthwindCRUD.Helpers; +using NorthwindCRUD.Models.DbModels; + +namespace NorthwindCRUD.Services { - using Microsoft.CodeAnalysis; - using Microsoft.EntityFrameworkCore; - using NorthwindCRUD.Constants; - using NorthwindCRUD.Helpers; - using NorthwindCRUD.Models.DbModels; - using NorthwindCRUD.Models.Dtos; - public class OrderService { private readonly DataContext dataContext; @@ -16,12 +16,6 @@ public OrderService(DataContext dataContext) this.dataContext = dataContext; } - private IQueryable GetOrdersQuery() - { - return this.dataContext.Orders - .Include(c => c.ShipAddress); - } - public OrderDb[] GetAll() { return this.dataContext.Orders @@ -37,10 +31,9 @@ public OrderDb[] GetNOrders(int numberOfOrdersToRetrieve) .ToArray(); } - public OrderDb GetById(int id) + public OrderDb? GetById(int id) { - return GetOrdersQuery() - .FirstOrDefault(c => c.OrderId == id); + return GetOrdersQuery().FirstOrDefault(c => c.OrderId == id); } public OrderDetailDb[] GetOrderDetailsById(int id) @@ -79,23 +72,21 @@ public OrderDetailDb[] GetOrderDetailsByProductId(int id) return details; } - public OrderDb Create(OrderDb model) { - if (this.dataContext.Customers.FirstOrDefault(c => c.CustomerId == model.CustomerId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Customer), model.CustomerId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Customer), model.CustomerId?.ToString())); } if (this.dataContext.Employees.FirstOrDefault(e => e.EmployeeId == model.EmployeeId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Employee), model.EmployeeId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Employee), model.EmployeeId.ToString())); } if (this.dataContext.Shippers.FirstOrDefault(s => s.ShipperId == model.ShipperId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Shipper), model.ShipperId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Shipper), model.ShipperId.ToString())); } var id = IdGenerator.CreateDigitsId(); @@ -105,15 +96,16 @@ public OrderDb Create(OrderDb model) id = IdGenerator.CreateDigitsId(); existWithId = this.GetById(id); } + model.OrderId = id; PropertyHelper.MakePropertiesEmptyIfNull(model); if (model.ShipAddress == null) { - var emptyAddress = this.dataContext.Addresses.FirstOrDefault(a => a.Street == ""); + var emptyAddress = this.dataContext.Addresses.FirstOrDefault(a => a.Street == string.Empty); model.ShipAddress = emptyAddress; - model.ShipAddressId = emptyAddress.AddressId; + model.ShipAddressId = emptyAddress?.AddressId; } var orderEntity = this.dataContext.Orders.Add(model); @@ -121,22 +113,22 @@ public OrderDb Create(OrderDb model) return orderEntity.Entity; } - - public OrderDb Update(OrderDb model) + + public OrderDb? Update(OrderDb model) { if (this.dataContext.Customers.FirstOrDefault(c => c.CustomerId == model.CustomerId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Customer), model.CustomerId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Customer), model.CustomerId?.ToString())); } if (this.dataContext.Employees.FirstOrDefault(e => e.EmployeeId == model.EmployeeId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Employee), model.EmployeeId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Employee), model.EmployeeId.ToString())); } if (this.dataContext.Shippers.FirstOrDefault(s => s.ShipperId == model.ShipperId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Shipper), model.ShipperId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Shipper), model.ShipperId.ToString())); } var orderEntity = this.dataContext.Orders @@ -147,8 +139,8 @@ public OrderDb Update(OrderDb model) { orderEntity.OrderDate = model.OrderDate != null ? model.OrderDate : orderEntity.OrderDate; orderEntity.RequiredDate = model.RequiredDate != null ? model.RequiredDate : orderEntity.RequiredDate; - orderEntity.ShipVia = model.ShipVia != null ? model.ShipVia : orderEntity.ShipVia; - orderEntity.Freight = model.Freight != null ? model.Freight : orderEntity.Freight; + orderEntity.ShipVia = model.ShipVia; // ShipVia has int type which can't be null + orderEntity.Freight = model.Freight; // Freight has double type which can't be null orderEntity.ShipName = model.ShipName != null ? model.ShipName : orderEntity.ShipName; orderEntity.EmployeeId = model.EmployeeId != null ? model.EmployeeId : orderEntity.EmployeeId; orderEntity.CustomerId = model.CustomerId != null ? model.CustomerId : orderEntity.CustomerId; @@ -156,7 +148,7 @@ public OrderDb Update(OrderDb model) if (model.ShipAddress != null) { var newAddress = this.dataContext.Addresses.FirstOrDefault(a => a.Street == model.ShipAddress.Street); - if (newAddress != null) + if (newAddress != null && orderEntity.ShipAddress != null) { orderEntity.ShipAddress.City = model.ShipAddress.City; orderEntity.ShipAddress.Region = model.ShipAddress.Region; @@ -178,7 +170,7 @@ public OrderDb Update(OrderDb model) return orderEntity; } - public OrderDb Delete(int id) + public OrderDb? Delete(int id) { var orderEntity = this.GetById(id); if (orderEntity != null) @@ -189,5 +181,11 @@ public OrderDb Delete(int id) return orderEntity; } + + private IQueryable GetOrdersQuery() + { + return this.dataContext.Orders + .Include(c => c.ShipAddress); + } } } diff --git a/NorthwindCRUD/Services/ProductService.cs b/NorthwindCRUD/Services/ProductService.cs index 7159efd..f2e4ad7 100644 --- a/NorthwindCRUD/Services/ProductService.cs +++ b/NorthwindCRUD/Services/ProductService.cs @@ -1,4 +1,5 @@ -using NorthwindCRUD.Constants; +using System.Globalization; +using NorthwindCRUD.Constants; using NorthwindCRUD.Helpers; using NorthwindCRUD.Models.DbModels; @@ -18,7 +19,7 @@ public ProductDb[] GetAll() return this.dataContext.Products.ToArray(); } - public ProductDb GetById(int id) + public ProductDb? GetById(int id) { return this.dataContext.Products.FirstOrDefault(p => p.ProductId == id); } @@ -42,14 +43,14 @@ public ProductDb[] GetProductsByIds(int[] productIds) public ProductDb Create(ProductDb model) { - if(this.dataContext.Categories.FirstOrDefault(c => c.CategoryId == model.CategoryId) == null) + if (this.dataContext.Categories.FirstOrDefault(c => c.CategoryId == model.CategoryId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Category), model.CategoryId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Category), model.CategoryId.ToString())); } if (this.dataContext.Suppliers.FirstOrDefault(s => s.SupplierId == model.SupplierId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Supplier), model.SupplierId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Supplier), model.SupplierId.ToString())); } var id = IdGenerator.CreateDigitsId(); @@ -59,6 +60,7 @@ public ProductDb Create(ProductDb model) id = IdGenerator.CreateDigitsId(); existWithId = this.GetById(id); } + model.ProductId = id; PropertyHelper.MakePropertiesEmptyIfNull(model); @@ -69,16 +71,16 @@ public ProductDb Create(ProductDb model) return productEntity.Entity; } - public ProductDb Update(ProductDb model) + public ProductDb? Update(ProductDb model) { if (this.dataContext.Categories.FirstOrDefault(c => c.CategoryId == model.CategoryId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Category), model.CategoryId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Category), model.CategoryId.ToString())); } if (this.dataContext.Suppliers.FirstOrDefault(s => s.SupplierId == model.SupplierId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Supplier), model.SupplierId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Supplier), model.SupplierId.ToString())); } var productEntity = this.dataContext.Products.FirstOrDefault(p => p.ProductId == model.ProductId); @@ -99,7 +101,7 @@ public ProductDb Update(ProductDb model) return productEntity; } - public ProductDb Delete(int id) + public ProductDb? Delete(int id) { var productEntity = this.GetById(id); if (productEntity != null) diff --git a/NorthwindCRUD/Services/RegionService.cs b/NorthwindCRUD/Services/RegionService.cs index 34bb78b..5766f57 100644 --- a/NorthwindCRUD/Services/RegionService.cs +++ b/NorthwindCRUD/Services/RegionService.cs @@ -5,7 +5,6 @@ namespace NorthwindCRUD.Services { public class RegionService { - private readonly DataContext dataContext; public RegionService(DataContext dataContext) @@ -18,7 +17,7 @@ public RegionDb[] GetAll() return this.dataContext.Regions.ToArray(); } - public RegionDb GetById(int id) + public RegionDb? GetById(int id) { return this.dataContext.Regions.FirstOrDefault(p => p.RegionId == id); } @@ -32,17 +31,18 @@ public RegionDb Create(RegionDb model) id = IdGenerator.CreateDigitsId(); existWithId = this.GetById(id); } + model.RegionId = id; PropertyHelper.MakePropertiesEmptyIfNull(model); - var RegionEntity = this.dataContext.Regions.Add(model); + var regionEntity = this.dataContext.Regions.Add(model); this.dataContext.SaveChanges(); - return RegionEntity.Entity; + return regionEntity.Entity; } - public RegionDb Update(RegionDb model) + public RegionDb? Update(RegionDb model) { var regionEntity = this.dataContext.Regions.FirstOrDefault(p => p.RegionId == model.RegionId); if (regionEntity != null) @@ -55,16 +55,16 @@ public RegionDb Update(RegionDb model) return regionEntity; } - public RegionDb Delete(int id) + public RegionDb? Delete(int id) { - var RegionEntity = this.GetById(id); - if (RegionEntity != null) + var regionEntity = this.GetById(id); + if (regionEntity != null) { - this.dataContext.Regions.Remove(RegionEntity); + this.dataContext.Regions.Remove(regionEntity); this.dataContext.SaveChanges(); } - return RegionEntity; + return regionEntity; } } } diff --git a/NorthwindCRUD/Services/SalesService.cs b/NorthwindCRUD/Services/SalesService.cs index 78c9b5d..8f0dffc 100644 --- a/NorthwindCRUD/Services/SalesService.cs +++ b/NorthwindCRUD/Services/SalesService.cs @@ -1,8 +1,6 @@ -using Microsoft.EntityFrameworkCore; -using NorthwindCRUD.Models.DbModels; +using System.Globalization; +using Microsoft.EntityFrameworkCore; using NorthwindCRUD.Models.Dtos; -using System; -using System.Globalization; namespace NorthwindCRUD.Services { @@ -21,6 +19,7 @@ public SalesDto[] GetSalesDataByCategoryAndYear(string categoryName, int? orderY { throw new ArgumentException("Category name is required.", nameof(categoryName)); } + var salesData = this.dataContext.OrderDetails .Include(o => o.Order) .Include(od => od.Product) @@ -28,13 +27,13 @@ public SalesDto[] GetSalesDataByCategoryAndYear(string categoryName, int? orderY .ToList(); var filteredData = salesData - .Where(od => od.Product.Category.Name == categoryName) + .Where(od => od.Product.Category?.Name == categoryName) .ToList(); if (orderYear != null) { filteredData = salesData - .Where(od => od.Product.Category.Name == categoryName && + .Where(od => od.Product.Category?.Name == categoryName && ConvertToOrderDate(od.Order.OrderDate).Year == orderYear) .ToList(); } @@ -43,7 +42,7 @@ public SalesDto[] GetSalesDataByCategoryAndYear(string categoryName, int? orderY { ProductId = od.Product.ProductId, QuantitySold = od.Quantity, - SaleAmount = od.Quantity * od.UnitPrice + SaleAmount = od.Quantity * od.UnitPrice, }).ToArray(); return sales; @@ -51,7 +50,6 @@ public SalesDto[] GetSalesDataByCategoryAndYear(string categoryName, int? orderY public SalesDto[] RetrieveSalesDataByCountry(string startDate, string endDate, string country) { - if (string.IsNullOrEmpty(startDate) || string.IsNullOrEmpty(endDate)) { throw new ArgumentException("startDate and endDate are required."); @@ -61,7 +59,8 @@ public SalesDto[] RetrieveSalesDataByCountry(string startDate, string endDate, s { throw new ArgumentException("Invalid date format for startDate or endDate."); } - string normalizedCountry = country.ToLower(); + + string normalizedCountry = country.ToLower(CultureInfo.InvariantCulture); var salesData = this.dataContext.OrderDetails .Include(o => o.Order) @@ -72,14 +71,14 @@ public SalesDto[] RetrieveSalesDataByCountry(string startDate, string endDate, s .ToList(); var filteredData = salesData - .Where(od => od.Order.ShipAddress.Country.ToLower() == normalizedCountry && DateTime.Parse(od.Order.OrderDate) >= parsedStartDate && DateTime.Parse(od.Order.RequiredDate) <= parsedEndDate) + .Where(od => od.Order.ShipAddress?.Country.ToLower(CultureInfo.InvariantCulture) == normalizedCountry && DateTime.Parse(od.Order.OrderDate, CultureInfo.InvariantCulture) >= parsedStartDate && DateTime.Parse(od.Order.RequiredDate, CultureInfo.InvariantCulture) <= parsedEndDate) .ToList(); var sales = filteredData.Select(od => new SalesDto { ProductId = od.Product.ProductId, QuantitySold = od.Quantity, - SaleAmount = od.Quantity * od.UnitPrice + SaleAmount = od.Quantity * od.UnitPrice, }).ToArray(); return sales; @@ -91,6 +90,7 @@ public SalesDto[] RetrieveSalesDataByYear(int year, int? startMonth, int? endMon { throw new ArgumentException("Year is required.", nameof(year)); } + var salesData = this.dataContext.OrderDetails .Include(o => o.Order) .Include(od => od.Product) @@ -100,7 +100,6 @@ public SalesDto[] RetrieveSalesDataByYear(int year, int? startMonth, int? endMon .Where(od => ConvertToOrderDate(od.Order.OrderDate).Year == year) .ToList(); - if (startMonth != 0) { filteredData = filteredData.Where(od => @@ -117,7 +116,7 @@ public SalesDto[] RetrieveSalesDataByYear(int year, int? startMonth, int? endMon { ProductId = od.Product.ProductId, QuantitySold = od.Quantity, - SaleAmount = od.Quantity * od.UnitPrice + SaleAmount = od.Quantity * od.UnitPrice, }).ToArray(); return sales; @@ -129,6 +128,7 @@ private DateTime ConvertToOrderDate(string dateString) { return result; } + throw new ArgumentException("Invalid date format"); } } diff --git a/NorthwindCRUD/Services/ShipperService.cs b/NorthwindCRUD/Services/ShipperService.cs index bc1017f..1fbca8b 100644 --- a/NorthwindCRUD/Services/ShipperService.cs +++ b/NorthwindCRUD/Services/ShipperService.cs @@ -17,7 +17,7 @@ public ShipperDb[] GetAll() return this.dataContext.Shippers.ToArray(); } - public ShipperDb GetById(int id) + public ShipperDb? GetById(int id) { return this.dataContext.Shippers.FirstOrDefault(p => p.ShipperId == id); } @@ -31,6 +31,7 @@ public ShipperDb Create(ShipperDb model) id = IdGenerator.CreateDigitsId(); existWithId = this.GetById(id); } + model.ShipperId = id; PropertyHelper.MakePropertiesEmptyIfNull(model); @@ -41,13 +42,13 @@ public ShipperDb Create(ShipperDb model) return shipperEntity.Entity; } - public ShipperDb Update(ShipperDb model) + public ShipperDb? Update(ShipperDb model) { var shipperEntity = this.dataContext.Shippers.FirstOrDefault(p => p.ShipperId == model.ShipperId); if (shipperEntity != null) { shipperEntity.Phone = model.Phone != null ? model.Phone : shipperEntity.Phone; - shipperEntity.CompanyName= model.CompanyName != null ? model.CompanyName : shipperEntity.CompanyName; + shipperEntity.CompanyName = model.CompanyName != null ? model.CompanyName : shipperEntity.CompanyName; this.dataContext.SaveChanges(); } @@ -55,7 +56,7 @@ public ShipperDb Update(ShipperDb model) return shipperEntity; } - public ShipperDb Delete(int id) + public ShipperDb? Delete(int id) { var shipperEntity = this.GetById(id); if (shipperEntity != null) diff --git a/NorthwindCRUD/Services/SupplierService.cs b/NorthwindCRUD/Services/SupplierService.cs index 3912392..6346cda 100644 --- a/NorthwindCRUD/Services/SupplierService.cs +++ b/NorthwindCRUD/Services/SupplierService.cs @@ -5,10 +5,9 @@ namespace NorthwindCRUD.Services { public class SupplierService { - private readonly DataContext dataContext; - public SupplierService( DataContext dataContext) + public SupplierService(DataContext dataContext) { this.dataContext = dataContext; } @@ -18,7 +17,7 @@ public SupplierDb[] GetAll() return this.dataContext.Suppliers.ToArray(); } - public SupplierDb GetById(int id) + public SupplierDb? GetById(int id) { return this.dataContext.Suppliers.FirstOrDefault(p => p.SupplierId == id); } @@ -32,6 +31,7 @@ public SupplierDb Create(SupplierDb model) id = IdGenerator.CreateDigitsId(); existWithId = this.GetById(id); } + model.SupplierId = id; PropertyHelper.MakePropertiesEmptyIfNull(model); @@ -42,7 +42,7 @@ public SupplierDb Create(SupplierDb model) return supplierEntity.Entity; } - public SupplierDb Update(SupplierDb model) + public SupplierDb? Update(SupplierDb model) { var supplierEntity = this.dataContext.Suppliers.FirstOrDefault(p => p.SupplierId == model.SupplierId); if (supplierEntity != null) @@ -65,7 +65,7 @@ public SupplierDb Update(SupplierDb model) return supplierEntity; } - public SupplierDb Delete(int id) + public SupplierDb? Delete(int id) { var supplierEntity = this.GetById(id); if (supplierEntity != null) diff --git a/NorthwindCRUD/Services/TerritoryService.cs b/NorthwindCRUD/Services/TerritoryService.cs index 6e56698..6099db8 100644 --- a/NorthwindCRUD/Services/TerritoryService.cs +++ b/NorthwindCRUD/Services/TerritoryService.cs @@ -1,4 +1,5 @@ -using NorthwindCRUD.Constants; +using System.Globalization; +using NorthwindCRUD.Constants; using NorthwindCRUD.Helpers; using NorthwindCRUD.Models.DbModels; @@ -6,7 +7,6 @@ namespace NorthwindCRUD.Services { public class TerritoryService { - private readonly DataContext dataContext; public TerritoryService(DataContext dataContext) @@ -19,31 +19,31 @@ public TerritoryDb[] GetAll() return this.dataContext.Territories.ToArray(); } - public TerritoryDb GetById(string id) + public TerritoryDb? GetById(string id) { return this.dataContext.Territories.FirstOrDefault(t => t.TerritoryId == id); } - public TerritoryDb[] GetTerritoriesByRegionId(int id) { return this.dataContext.Territories.Where(t => t.RegionId == id).ToArray(); - } + } public TerritoryDb Create(TerritoryDb model) { if (this.dataContext.Regions.FirstOrDefault(r => r.RegionId == model.RegionId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Region), model.RegionId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Region), model.RegionId.ToString())); } - var id = IdGenerator.CreateDigitsId().ToString(); + var id = IdGenerator.CreateDigitsId().ToString(CultureInfo.InvariantCulture); var existWithId = this.GetById(id); while (existWithId != null) { - id = IdGenerator.CreateDigitsId().ToString(); + id = IdGenerator.CreateDigitsId().ToString(CultureInfo.InvariantCulture); existWithId = this.GetById(id); } + model.TerritoryId = id; PropertyHelper.MakePropertiesEmptyIfNull(model); @@ -54,11 +54,11 @@ public TerritoryDb Create(TerritoryDb model) return territoryEntity.Entity; } - public TerritoryDb Update(TerritoryDb model) + public TerritoryDb? Update(TerritoryDb model) { if (this.dataContext.Regions.FirstOrDefault(r => r.RegionId == model.RegionId) == null) { - throw new InvalidOperationException(string.Format(StringTemplates.InvalidEntityMessage, nameof(model.Region), model.RegionId.ToString())); + throw new InvalidOperationException(string.Format(CultureInfo.InvariantCulture, StringTemplates.InvalidEntityMessage, nameof(model.Region), model.RegionId.ToString())); } var territoryEntity = this.dataContext.Territories.FirstOrDefault(p => p.TerritoryId == model.TerritoryId); @@ -73,7 +73,7 @@ public TerritoryDb Update(TerritoryDb model) return territoryEntity; } - public TerritoryDb Delete(string id) + public TerritoryDb? Delete(string id) { var territoryEntity = this.GetById(id); if (territoryEntity != null)