>Xây dựng CRUD cho ứng dụng Web API với ASP.Net core

Xây dựng CRUD cho ứng dụng Web API với ASP.Net core

29/05/2024

Cách thiết lập một ứng dụng web api cơ bản sử dụng .Net core 8.0 gồm các bước cơ bản sau:

Bước 1: Thiết lập và tạo project cho ứng dụng Web API sử dụng .Net Core


Bước 2: Thiết lập và cài đặt thư viện

dotnet add package Microsoft.EntityFrameworkCore --version 8.0.6 
dotnet add package Microsoft.EntityFrameworkCore. Design --version 8.0.6
dotnet add package Microsoft.EntityFrameworkCore. SqlServer --version 8.0.6
dotnet add package AutoMapper --version 13.0.1

Bước 3: Thiết lập cơ sở dữ liệu:

USE [Example]
GO
CREATE TABLE [dbo].[Sample](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [Title] [nvarchar](100) NOT NULL,
    [Description] [nvarchar](500) NULL,
    [DueDate] [datetime] NOT NULL,
    [CreatedAt] [datetime] NULL,
    [UpdatedAt] [datetime] NULL,
CONSTRAINT [PK_Sample] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF) ON [PRIMARY]
) ON [PRIMARY]
GO

Bước 4: Tạo model Sample

   [Table("Sample")]
   public class Sample
   {
       [Key]
       public int ID { get; set; }
       public string Title { get; set; }
       public string Description { get; set; }
       public DateTime DueDate { get; set; }
       public DateTime? CreatedAt { get; set; }
       public DateTime? UpdatedAt { get; set; }
   }

Bước 5: Thiết lập Database Context (EF)
 

   public class SampleDbContext : DbContext
   {
       public SampleDbContext( DbContextOptions< SampleDbContext > options)  :  base(options)
       {
       }

       public DbSet< Sample > Samples { get; set; }
   }

Bước 6: Xác định đối tượng truyền dữ liệu (DTO)
- Tạo class dùng để truyền data khi create:
 

   public class CreateSampleRequest
   {
       [Required]
       [JsonRequired]
       [StringLength(100)]
       public string Title { get; set; }

       [StringLength(500)]
       public string Description { get; set; }

       [Required]
       [JsonRequired]
       public DateTime DueDate { get; set; }
   }

- Tạo class dùng để truyền data khi create:

   public class UpdateSampleRequest
   {
       [StringLength(100)]
       public string? Title { get; set; }

       [StringLength(500)]
       public string? Description { get; set; }

       public DateTime? DueDate { get; set; }
   }

Bước 7: Triển khai Object Mapping cho dữ liệu Sample

   public class AutoMapperProfile : Profile
   {
       public AutoMapperProfile()
       {
           CreateMap<CreateSampleRequest, Sample>()
               .ForMember(dest => dest.ID, opt => opt.Ignore())
               .ForMember(dest => dest.CreatedAt, opt => opt.Ignore())
               .ForMember(dest => dest.UpdatedAt, opt => opt.Ignore());

           CreateMap<UpdateSampleRequest, Sample>()
               .ForMember(dest => dest.ID, opt => opt.Ignore())
               .ForMember(dest => dest.CreatedAt, opt => opt.Ignore())
               .ForMember(dest => dest.UpdatedAt, opt => opt.Ignore())
               .ConvertUsing(new NullValueIgnoringConverter < UpdateSampleRequest , Sample >());
       }
   }

Bước 8: Triển khai Class Repository
- Tạo interface generic kiểu T:

   public interface IRepository<T> where T : class
   {
       Task<IReadOnlyList<T>> GetAllAsync();
       Task<T?> GetByIDAsync(int id);
       Task CreateAsync(T entity);
       void Update(T entity);
       void Delete(T entity);
       Task SaveChangeAsync();
   }

- Tạo class Repository generic kiểu T:

   public class Repository<T> : IRepository<T> where T : class
   {
       private readonly DbContext appDbContext;
       private DbSet<T> entities;

       public Repository(DbContext context)
       {
           this.appDbContext = context;
           entities = appDbContext.Set<T>();
       }

       public Task SaveChangeAsync() => appDbContext. SaveChangesAsync();

       public async Task< IReadOnlyList<T> > GetAllAsync()
       {
           return await entities.ToListAsync();
       }

       public async Task<T?> GetByIDAsync(int id)
       {
           var entity = await entities.FindAsync(id);
           if (entity == null)
           {
               return null!;
           }
           return entity;
       }

       public async Task CreateAsync(T entity)
       {
           await entities.AddAsync(entity);
       }

       public void Delete(T entity)
       {
           entities.Remove(entity);
       }

       public void Update(T entity)
       {
           entities.Update(entity);
       }
   }

- Tạo interface Repository tương ứng cho model Sample

   public interface ISampleRepository : IRepository<Sample>
   {
   }

- Tạo class Repository tương ứng cho model Sample

   public class SampleRepository : Repository< Sample >,  ISampleRepository
   {
       public SampleRepository( SampleDbContext context ) : base(context)
       {
       }
   }

Bước 9: Triển khai Class Service
- Tạo interface Service tương ứng cho model Sample
 

   public interface ISampleService
   {
       Task<IEnumerable<Sample>> GetAllAsync();
       Task<Sample> GetSampleIdAsync( int id);
       Task CreateSampleAsync( CreateSampleRequest request );
       Task UpdateSample( int id, UpdateSampleRequest request );
       Task DeleteSampleAsync( int id );
   }

- Tạo Class Service tương ứng cho model Sample

   public class SampleService : ISampleService
   {
       private ISampleRepository sampleRepository;
       private IMapper mapper;
       private readonly ILogger<SampleService> logger;
       public SampleService( ISampleRepository sampleRepository, IMapper mapper, ILogger<SampleService> logger)
       {
           this.sampleRepository = sampleRepository;
           this.mapper = mapper;
           this.logger = logger;
       }
   }

Bước 10: Triển khai Phương thức GetAllAsync trong Class Service
 

      public async Task<IEnumerable<Sample>> GetAllAsync()
       {
           var res = await sampleRepository.GetAllAsync();
           if (res == null)
           {
               logger.LogInformation($" No Sample items found");
           }
           return res;
       }


Bước 11: Triển khai Phương thức GetByIdAsync trong Class Service
 

       public async Task<Sample> GetSampleIdAsync(int id)
       {
           var res = await sampleRepository.GetByIDAsync(id);
           if (res == null)
           {
               logger.LogInformation($"No Sample item with Id {id} found.");
           }
           return res;
       }

Bước 12: Triển khai Phương thức CreateSampleAsync trong Class Service
 

      public async Task CreateSampleAsync( CreateSampleRequest request )
       {
           try
           {
               // DATA
               var dataAdd = mapper.Map<Sample>(request);
               dataAdd.CreatedAt = DateTime.Now;

               // CREATE & SAVE
               await sampleRepository. CreateAsync( dataAdd);
               await sampleRepository. SaveChangeAsync();
           }
           catch (Exception ex)
           {
               logger.LogError(ex, "An error occurred while creating the todo item.");
           }
       }

Bước 13: Triển khai Phương thức UpdateSampleAsync trong Class Service
 

       public async Task UpdateSample( int id, UpdateSampleRequest request)
       {
           try
           {
               // FINDED
               var dataTable = await sampleRepository.GetByIDAsync(id);
               if (dataTable != null)
               {
                   var dataUpdate = mapper.Map(request, dataTable);
                   dataUpdate.UpdatedAt = DateTime.Now;

                   // UPDATE & SAVE
                   sampleRepository. Update(dataUpdate);
                   await sampleRepository. SaveChangeAsync();
               }
               else
               {
                   logger.LogInformation($" No Sample items found");
               }
           }
           catch (Exception ex)
           {
               logger.LogError(ex, "An error occurred while updating the todo item.");
           }
       }

Bước 14: Triển khai Phương thức DeleteSampleAsync trong Class Service

       public async Task DeleteSampleAsync(int id)
       {
           try
           {
               // FINDED
               var data = await sampleRepository.GetByIDAsync(id);
               if (data != null)
               {
                   // DELETE & SAVE
                   sampleRepository.Delete(data);
                   await sampleRepository.SaveChangeAsync();

               }
               else
               {
                   logger.LogInformation($"No item found with the id {id}");
               }
           }
           catch (Exception ex)
           {

               logger.LogError(ex, "An error occurred while remove the todo item.");
           }
       }

Bước 15: Tạo lớp SampleController

   [ApiController]
   [Route("api/[controller]")]
   public class SampleController : Controller
   {
       private readonly ISampleService sampleService;

       public SampleController(ISampleService sampleService)
       {
           this.sampleService = sampleService;
       }
   }

Bước 16: Triển khai Phương thức GetAllAsync trong Lớp SampleController

       [HttpGet]
       public async Task<IActionResult> GetAllAsync()
       {
           try
           {
               var Sample = await sampleService.GetAllAsync();

               if (Sample == null || !Sample.Any())
               {
                   return Ok(new { message = "No Sample Items found" });
               }

               return Ok(new { message = "Successfully retrieved all sample ", data = Sample });
           }
           catch (Exception ex)
           {
               return StatusCode(500, new { message = "An error occurred while retrieving all sample it", error = ex.Message });
           }
       }

Bước 17: Triển khai Phương thức GetByIdAsync trong Lớp SampleController

       [HttpGet("{id:int}")]
       public async Task<IActionResult> GetSampleIdAsync(int id)
       {
           try
           {
               var Sample = await sampleService.GetSampleIdAsync(id);
               if (Sample == null)
               {
                   return NotFound(new { message = $"Sample Item  with id {id} not found" });
               }

               return Ok(new { message = "Successfully retrieved all sample ", data = Sample });
           }
           catch (Exception ex)
           {
               return StatusCode(500, new { message = "An error occurred while retrieving all sample it", error = ex.Message });
           }
       }

Bước 18: Triển khai Phương thức CreateSampleAsync trong Lớp SampleController

       [HttpPost]
       public async Task<IActionResult> CreateSampleAsync( CreateSampleRequest request)
       {
           try
           {
               if (!ModelState.IsValid)
               {
                   return BadRequest(ModelState);
               }

               await sampleService. CreateSampleAsync( request);
               return Ok(new { message = "Sample successfully created" });
           }
           catch (Exception ex)
           {
               return StatusCode(500, new { message = "An error occurred while creating the crating Sample Item", error = ex.Message });
           }
       }

Bước 19: Triển khai Phương thức UpdateSampleAsync trong Lớp SampleController

       [HttpPut("{id:int}")]
       public async Task<IActionResult> UpdateSampleAsync(int id, UpdateSampleRequest request)
       {
           try
           {
               if (!ModelState.IsValid)
               {
                   return BadRequest(ModelState);
               }

               var Sample = await sampleService.GetSampleIdAsync(id);
               if (Sample == null)
               {
                   return NotFound(new { message = $"Sample Item  with id {id} not found" });
               }

               await sampleService.UpdateSample(id, request);
               return Ok(new { message = $" Sample Item  with id {id} successfully updated" });
           }
           catch (Exception ex)
           {
               return StatusCode(500, new { message = $"An error occurred while updating sample with id {id}", error = ex.Message });
           }
       }

Bước 20: Triển khai Phương thức DeleteSampleAsync trong Lớp SampleController

       [HttpDelete("{id:int}")]
       public async Task<IActionResult> DeleteSampleAsync(int id)
       {
           try
           {
               var Sample = await sampleService.GetSampleIdAsync(id);
               if (Sample == null)
               {
                   return NotFound(new { message = $"Sample Item  with id {id} not found" });
               }

               await sampleService.DeleteSampleAsync(id);
               return Ok(new { message = $"Sample  with id {id} successfully deleted" });
           }
           catch (Exception ex)
           {
               return StatusCode(500, new { message = $"An error occurred while deleting Sample Item  with id {id}", error = ex.Message });
           }
       }

Bước 21: Kiểm tra config trong file Program.cs

       // ConnectDB
       builder.Services. AddDbContext<SampleDbContext>(options =>
           options.UseSqlServer( builder.Configuration. GetConnectionString( "SampleDbContextConnection")));

       // AutoMapper
       builder.Services. AddAutoMapper( AppDomain. CurrentDomain.GetAssemblies());

       // Services
       builder.Services. AddScoped( typeof(IRepository<> ), typeof( Repository<> ));
       builder.Services. AddScoped< ISampleRepository, SampleRepository >();
       builder.Services. AddScoped< ISampleService, SampleService>();

Bước 22: Kiểm tra điểm cuối API của bạn với Postman hoặc Swagger
 -Kết quả khi chạy source.

 -Kết quả khi check postman Lấy danh sách Sample

 -Kết quả khi check postman Lấy một  Sample cụ thể.

 -Kết quả khi check postman Thêm mới một Sample

 -Kết quả khi check postman Cập nhật một Sample

 -Kết quả khi check postman Xóa một Sample

Link tham khảo source code 

Cảm ơn bạn chúc bạn thành công!

Copyright © 2024 by 365learning