Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
May 10, 2021 06:11 pm GMT

Build a Generic CRUD API with ASP.NET Core

In the process of creating CRUD controllers, we can repeat a lot of code and go against the DRY principle. To avoid that, I'm going to show you how to build a generic base controller, then you will only have to create controllers that inherit from the base controller, and that's it. The controllers will already have the basic CRUD methods.

I saw a lot of articles about the Generic Repository Pattern. What I'm going to show you is not a Repository Pattern. EF Core is already based on the Unit of Work and Repository Pattern. Thus, we can use the DbContext class directly from our controllers, and that's what we're going to do. Anyway, you can find more information about Using a custom repository versus using EF DbContext directly here. With that said, let's start to build our Generic CRUD API.

Base Model

At first, let's define the base model for our entities. For operations like edit and delete we need an Id property, and we can have some timestamp properties for audit as well. So EntityBase looks like:

using System;namespace GenericCrudApi.Models{    public class EntityBase    {        public long Id { get; set; }        public DateTime CreationDate { get; set; }        public DateTime? ModificationDate { get; set; }    }}

Generic Base Controller

Now, we are ready to implement our generic controller. It will be an abstract class because it will be the base class for our controllers, and we'll mark the CRUD methods as virtual since we need to be able to override them in our inherited controllers if necessary. So CrudControllerBase looks like:

using System;using System.Threading.Tasks;using GenericCrudApi.Models;using Microsoft.AspNetCore.Mvc;using Microsoft.EntityFrameworkCore;namespace GenericCrudApi.Controllers{    [ApiController]    [Route("api/[controller]")]    public class CrudControllerBase<T>: ControllerBase where T: EntityBase    {        protected readonly DataContext _context;        public CrudControllerBase(DataContext context)        {            _context = context;        }        [HttpGet]        public virtual async Task<IActionResult> List()        {            var entities = await _context.Set<T>().ToListAsync();            return Ok(entities);        }        [HttpGet("{id}")]        public virtual async Task<IActionResult> Detail(long id)        {            var entity = await _context.Set<T>().FindAsync(id);            if (entity == null)                return NotFound();            return Ok(entity);        }        [HttpPost]        public virtual async Task<IActionResult> Create(T entity)        {            entity.CreationDate = DateTime.Now;            await _context.Set<T>().AddAsync(entity);            await _context.SaveChangesAsync();            return CreatedAtAction("Detail", new { id = entity.Id }, entity);        }        [HttpPut("{id}")]        public virtual async Task<IActionResult> Update(long id, T entity)        {            if (id != entity.Id)                return BadRequest();            if (!await EntityExists(id))                return NotFound();            entity.ModificationDate = DateTime.Now;            _context.Entry(entity).State = EntityState.Modified;            try            {                await _context.SaveChangesAsync();            }            catch (DbUpdateConcurrencyException)            {                throw;            }            return NoContent();        }        [HttpDelete("{id}")]        public async Task<IActionResult> Delete(long id)        {            var entity = await _context.Set<T>().FindAsync(id);            if (entity == null)                return NotFound();            _context.Set<T>().Remove(entity);            await _context.SaveChangesAsync();            return NoContent();        }        private Task<bool> EntityExists(long id)        {            return _context.Set<T>().AnyAsync(e => e.Id == id);        }    }}

Note: _context.Set<T>()

Returns a DbSet instance for access to entities of the given type in the context and the underlying store.

Inheriting from the Generic Base Controller

It's time to see our base controller in action, for this we're going to create a TodoItem controller by extending the CrudControllerBase.

namespace GenericCrudApi.Models{    public class TodoItem: EntityBase    {        public string Name { get; set; }        public bool IsComplete { get; set; }    }}
using GenericCrudApi.Models;using Microsoft.AspNetCore.Mvc;namespace GenericCrudApi.Controllers{    public class TodoItemsController: CrudControllerBase<TodoItem>    {        public TodoItemsController(DataContext context)         : base(context){}    }}

And thats it. Now we can test the HTTP methods with Postman:

Captura de pantalla de 2021-05-09 15-28-26.png

Finally, to finish implementing our base controller and make it completely reusable, we need to add filtering, sorting and pagination features. So if you liked this article, please let me know in the comments and stay around. I'm going to write about it in future articles. Thanks for reading!


Original Link: https://dev.to/guivern/build-a-generic-crud-api-with-asp-net-core-adf

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To