11.05.2023
Моя цель — изучить C# и поделиться своими знаниями с людьми. Я упомянул примеры с кодами комментариев.
Мы продолжим RentCarProject(ReCapProject)
Требования:
1. -Создайте таблицу CarImages (Id, CarId, ImagePath, Date). Каждый автомобиль может иметь более 1 фотографии.
2. -Прописать систему в API, когда будем добавлять Фото Авто…
3. -Изображения будут храниться в папке вашего проекта. Изображения будут сохранены с идентификатором GUID, который вы сами предоставите, а не с именем, которое они загружают.
4. -Добавить метод фотографий = Удалить, Обновить
5. -1 машина может иметь 5 фотографий.
6. -Когда добавлены фотографии автомобиля, затем сохранены фотографии, которые были добавлены, тогда мы можем увидеть в системе это…
7. -Создайте систему для списка фотографий автомобилей.
8. -Создайте систему. Если по умолчанию выбраны фотографии автомобилей, система может отображать фотографии по умолчанию. Это означает логотип компании (список одного элемента).
1-)
Сначала я создал как сущность в EntityLayer
namespace Entities.Concrete { public class CarImage : IEntity { public int Id { get; set; } public int CarId { get; set; } public string ImagePath { get; set; } public DateTime ImageDate { get; set; } } }
Некоторые классы с кодами, но некоторые классы без кода, но позже я добавлю коды, потому что некоторое время мы должны следовать методу блок-схемы, чтобы упорядочить классы. Но некоторые классы не нуждаются в рефакторинге, поэтому я буду делиться с кодами. можете увидеть их коды с комментариями ниже. Также вы можете понять с пространством имен, какой слой и классы…
namespace DataAccess.Abstract { //CarImage is generic and it will use as a entity... public interface ICarImageDal : IEntityRepository <CarImage> { } }
namespace DataAccess.Concrete.EntityFramework { public class EfCarImageDal : EfEntityRepositoryBase<CarImage,CarContext>,ICarImageDal { } }
И Первые Требования закончены…
2-) Мы хотим добавить фотографии автомобилей, тогда нам нужно написать коды в бизнес-уровне классов Service и Manager. Теперь я напишу просто метод Add, а затем позже я добавлю другие операции, это означает операцию CRUD в других требования…
Давайте сначала напишем в ICarImageService
namespace Business.Abstract { public interface ICarImageService { IResult Add(CarImage carImage); }
Я добавлю другие операции, которые хочу сначала показать, по какому пути мы идем.
namespace Business.Concrete { public class CarImageManager : ICarImageService { ICarImageDal _carImageDal; public CarImageManager(ICarImageDal carImageDal) { _carImageDal = carImageDal; } public IResult Add(CarImage carImage) { _carImageDal.Add(carImage); return new SuccessResult(Messages.ImageAdded); } } }
Теперь мы можем создать операцию добавления WepAPI…
Давайте напишем метод Add в этом классе CarImagesController WebAPI…
namespace WebAPI.Controllers { [Route("api/[controller]")] [ApiController] public class CarImagesController : ControllerBase { //Firstly Let's create the Loosely Coopled... ICarImageService _carImageService; public CarImagesController(ICarImageService carImageService) { _carImageService = carImageService; } //Used add naming to understand [HttpPost("add")] //Used CarImage to added entity for database public IActionResult Add(CarImage carImage) { //carimage coming from UI then added the system var result = _carImageService.Add(carImage); if (result.Success) { //http 200 code return Ok(result); } //http 400 code return BadRequest(result); } } }
Затем мы также должны добавить экземпляр и серверную часть в API, поэтому мы должны добавить ссылки на сервисы…
В классе OutofacBusinessModule.
builder.RegisterType<CarImageManager>().As<ICarImageService>().SingleInstance(); builder.RegisterType<EfCarImageDal>().As<ICarImageDal>().SingleInstance(); builder.RegisterType<FileHelperManager>().As<IFileHelperService>().SingleInstance();
Завершите 2.Требования…
3–4-)
Давайте добавим GUID…
GUID = глобальный уникальный идентификатор
CreatGuid() может создавать случайный GUID, а также возвращает этот GUID, преобразовывая его в строку.
GUID имеет 128-битные случайные идентификаторы, поэтому они не могут быть найдены. Его можно использовать для базы данных, веб-сайтов, электронной почты, идентификатора файла и т. Д., Мы можем использовать множество областей для их идентификатора.
Почему мы используем этот метод, потому что мы можем легко и безопасно найти файл или электронную почту.
namespace Core.Utilities.Helpers.GuidHelpers { public class GuidHelpers { public static string CreatGuid() { return Guid.NewGuid().ToString(); } } }
Создан файл FileHelper и созданы FileHelperService и FileHelperManager, чтобы найти файл для сохранения фотографий…
namespace Core.Utilities.Helpers.FileHelper { public interface IFileHelperService { //IFormFile Http protocol to which file will upload,Root is which way will follow... string Upload(IFormFile file, string root); void Delete(string filepath); string Update(IFormFile file, string filePath, string root); } }
Затем менеджер мы можем управлять ими в этом классе с комментариями.
namespace Core.Utilities.Helpers.FileHelper { //in this Class we will do CRUD(Create,Read,Update,Delete) operations for file. public class FileHelperManager : IFileHelperService { //We can upload the File in this root(in this way) //filepath is coming from ICarImageManager ,root is =jpeg it means way,which type of file public string Upload(IFormFile file, string root) { //if File Length is 0 return the null //it has a byte it means... it has a memory or no checking if (file.Length > 0) { //it is checking .jpeg have or no doesnt have it will create the way. if (!Directory.Exists(root)) { //this one is for UI memory working like that.firstly checking (random way=we created for photos in manager) have or no then //dont have then again create the way for IU to save file in the service Directory.CreateDirectory(root); } //extension is defined the extention variables file name string extension = Path.GetExtension(file.FileName); //which way will use the system we created random file way like that for safe.and guid was defined the this random numbers in the jpeg. string guid = GuidHelpers.GuidHelpers.CreatGuid(); //then filepath was defined the total name and which way string filePath = guid + extension; //root and filepath created with IDısposable pattern //it means after do that then will deleted with garbage collector using (FileStream fileStream = File.Create(root + filePath)) { //it is defined the with copy method in file full name file.CopyTo(fileStream); //then delete the flush in memory to new something. fileStream.Flush(); return filePath; } } return null; } //filepath is coming from ICarImageManager public void Delete(string filePath) {//if filepath way has a same file then we can delete the filePath if (File.Exists(filePath)) { File.Delete(filePath); } } public string Update(IFormFile file, string filePath, string root) { //firstly We are checking file have or no than if it has firstly delete it then Upload the new file with way(root) if (File.Exists(filePath)) { File.Delete(filePath); } return Upload(file, root); } } }
Также мы хотим добавить правила в операцию CRUD, поэтому мы используем BusinessRules. Давайте создадим его.
Почему мы используем бизнес-правила на основном уровне, потому что они могут обеспечить устойчивость, и мы можем проверить все правила в операции CRUD. Также мы использовали полиморфизм, чтобы использовать больше, чем правила, там вы можете увидеть внизу коды с комментариями…!
namespace Core.Utilities.Business { //if we create the Service it will be overdesign... public class BusinessRules { public static IResult Run(params IResult[] logics) { foreach ( var logic in logics) { //if logic unsuccess then it will give us the error. if (!logic.Success) { return logic; } } //if succes it can do operations. return null; } } }
Теперь мы можем добавить правила в менеджере.
Нам нужен ConstantsPath для файлов Давайте создадим его…
namespace Business.Constants { public class PathConstants { public const string CarImagesPath = "root\\Uploads\\CarImages"; } }
5,6,7,8)
Сначала добавлены все сервисы в BusinessLayer…
Все операции Crud и бизнес-правила внизу
public interface ICarImageService { IDataResult<List<CarImage>> GetImagesByCarId(int id); IDataResult<List<CarImage>> GetAll(); IDataResult<CarImage> GetById(int id); IResult Add(IFormFile file,CarImage carImage); IResult Update(IFormFile file,CarImage carImage); IResult Delete(CarImage carImage); }
Затем работает в ManagerClass для CarImage на бизнес-уровне.
namespace Business.Concrete { public class CarImageManager : ICarImageService { ICarImageDal _carImageDal; IFileHelperService _fileHelperService; public CarImageManager(ICarImageDal carImageDal,IFileHelperService fileHelperService) { _carImageDal = carImageDal; _fileHelperService = fileHelperService; } //IFormFile it means for HTTP protocol for file to request. public IResult Add(IFormFile file, CarImage carImage) { //used the Polymorphism to use rules. I wrote the rule method at below side IResult result = BusinessRules.Run(CheckForCarImageLimit(carImage.CarId)); if (result != null) { return result; } carImage.ImagePath = _fileHelperService.Upload(file, PathConstants.CarImagesPath); carImage.ImageDate = DateTime.Now; _carImageDal.Add(carImage); return new SuccessResult(Messages.ImageAdded); } public IResult Delete(CarImage carImage) { //for safety we added each other after that we can find the way then we can delete it. _fileHelperService.Delete(PathConstants.CarImagesPath + carImage.ImagePath); //then we delete the in dataBase. _carImageDal.Delete(carImage); return new SuccessResult(Messages.CarImageDeleted); } public IDataResult<CarImage> GetById(int id) { return new SuccessDataResult<CarImage>(_carImageDal.Get(i => i.Id == id), Messages.ImagesListedById); } public IResult Update(IFormFile file, CarImage carImage) { //Firstly Update the ImageFilePath carImage.ImagePath = _fileHelperService.Update(file, PathConstants.CarImagesPath + carImage.ImagePath, PathConstants.CarImagesPath); //Then Update the Upload time for image.When they uploaded in the system. carImage.ImageDate = DateTime.Now; //Then Update the Database ImageFilePath _carImageDal.Update(carImage); //everything Success result messages return new SuccessResult(Messages.ImageUpdated); } public IDataResult<List<CarImage>> GetAll() { return new SuccessDataResult<List<CarImage>>(_carImageDal.GetAll(), Messages.ImagesListed); } public IDataResult<List<CarImage>> GetImagesByCarId(int id) { IResult result = BusinessRules.Run(CheckImageExists(id)); if (result != null) { return new ErrorDataResult<List<CarImage>>(GetDefaultImage(id).Data); } return new SuccessDataResult<List<CarImage>>(_carImageDal.GetAll(c => c.CarId == id), Messages.ImagesListedByCarId); } //ImageLimit can not more 5 photos... private IResult CheckForCarImageLimit(int carId) { var result = _carImageDal.GetAll(i => i.CarId == carId).Count; if (result > 5) { return new ErrorResult(Messages.CarImageLimitReached); } return new SuccessResult(); } private IResult CheckImageExists(int carId) { var result = _carImageDal.GetAll(i => i.CarId == carId).Count; if (result > 0) { return new ErrorResult(Messages.CarImageAlreadyHave); } return new SuccessResult(); } private IDataResult<List<CarImage>> GetDefaultImage(int carId) { List<CarImage> carImages = new List<CarImage>(); carImages.Add(new CarImage { CarId = carId, ImageDate = DateTime.Now, ImagePath = "DefaultImage.jpg" }); return new SuccessDataResult<List<CarImage>>(carImages); } } }
Также, когда мы подключаемся к серверу PostgreSql, выдается ошибка времени, поэтому мы должны сопоставить время
Затем я ищу и могу найти подобное решение времени.
И подключитесь к базе данных для CarImage
namespace DataAccess.Concrete.EntityFramework { //Context is matching Db files and project classes... public class CarContext:DbContext { //we are selecting the which database protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseNpgsql(@"Host = localhost; Username = postgres; Password = 1234; Database = RentCarDB; Pooling = true;"); //Connection String.. //for time enable to working with together time. AppContext.SetSwitch("Npgsql.EnableLegacyTimestampBehavior", true); } //which object in sql server match which object in project we are doint it public DbSet<Car> Cars { get; set; } public DbSet<Brand> Brands { get; set; } public DbSet<Color> Colors { get; set; } public DbSet<User> Users { get; set; } public DbSet<Customer> Customers { get; set; } public DbSet<Rental> Rentals { get; set; } public DbSet<CarImage> CarImages { get; set; } } }
Затем я добавил всю операцию CRUD для файла изображения в webAPI, давайте посмотрим коды с комментариями…
namespace WebAPI.Controllers { [Route("api/[controller]")] [ApiController] public class CarImagesController : ControllerBase { //Firstly Let's create the Loosely Coopled... ICarImageService _carImageService; public CarImagesController(ICarImageService carImageService) { _carImageService = carImageService; } //Used add naming to understand [HttpPost("add")] //Used CarImage to added entity for database public IActionResult Add([FromForm] IFormFile file, [FromForm] CarImage carImage) { //carimage coming from UI then added the system var result = _carImageService.Add(file,carImage); if (result.Success) { //http 200 code return Ok(result); } //http 400 code return BadRequest(result); } [HttpPost("update")] public IActionResult Update([FromForm] IFormFile file , [FromForm] CarImage carImage) { var result = _carImageService.Update(file, carImage); if (result.Success) { return Ok(result); } return BadRequest(result); } [HttpPost("delete")] public IActionResult Delete(CarImage carImage) { //We find the which Id in DataBase var carDeleteImage = _carImageService.GetById(carImage.Id).Data; //then we deleted in the database var result = _carImageService.Delete(carDeleteImage); if (result.Success) { return Ok(result); } return BadRequest(result); } [HttpGet("getall")] public IActionResult GetAll() { var result = _carImageService.GetAll(); if (result.Success) { return Ok(result); } return BadRequest(result); } [HttpGet("getbyid")] public IActionResult GetbyId(int id) { var result = _carImageService.GetById(id); if (result.Success) { return Ok(result); } return BadRequest(result); } [HttpGet("getimagebycarid")] public IActionResult GetImagesByCarId(int carId) { var result = _carImageService.GetImagesByCarId(carId); if (result.Success) { return Ok(result); } return BadRequest(result); } } }
Давайте попробуем в Postman
файл должен выбрать параметры файла, а затем добавить jpeg с ПК.
Затем мы можем добавить их в Postman.
GitHup=https://github.com/muratozeee/ReCapProject