Loading, please wait...

A to Z Full Forms and Acronyms

Delete and Search in ASP.NET Core REST API.

In this article we will discuss, how to delete a resource, i.e implement HTTP DELETE in ASP.NET Core REST API and how to implement a search feature in ASP.NET Core REST API.

Delete in ASP.NET Core REST API

To delete an asset, issue an HTTP DELETE solicitation to the URI/api/employees/ID. The ID of the representative to delete must be passed in the URI.

 

ASP.NET Core REST API - HTTP DELETE Example

[Route("api/[controller]")]
[ApiController]
public class EmployeesController : ControllerBase
{
    private readonly IEmployeeRepository employeeRepository;

    public EmployeesController(IEmployeeRepository employeeRepository)
    {
        this.employeeRepository = employeeRepository;
    }

    [HttpDelete("{id:int}")]
    public async Task<ActionResult<Employee>> DeleteEmployee(int id)
    {
        try
        {
            var employeeToDelete = await employeeRepository.GetEmployee(id);

            if (employeeToDelete == null)
            {
                return NotFound($"Employee with Id = {id} not found");
            }

            return await employeeRepository.DeleteEmployee(id);
        }
        catch (Exception)
        {
            return StatusCode(StatusCodes.Status500InternalServerError,
                "Error deleting data");
        }
    }
}

Code Explanation

It is the DELETE demand that is utilized to delete a current representative. This is the explanation DeleteEmployee() strategy is enlivened with the HttpDelete trait.

The id of the worker to delete is passed as a boundary to the HttpDelete trait. This id will be attached to the URL/api/employees. So the URL becomes/api/employees/id.

[HttpDelete("{id:int}")]
public async Task<ActionResult<Employee>> DeleteEmployee(int id)

The worker id esteem in the URL is naturally planned to the id boundary on the DeleteEmployee(int id) technique.

As we are utilizing the int course constraint on the id course boundary, the id esteem in the URL is planned to the strategy boundary, just if the worth is an integer.

ASP.NET Core Web API CRUD Operations Example

Coming up next is the finished EmployeesController code. We have all the CRUD operations (i.e Create, Read, Update, and Delete) actualized.

using EmployeeManagement.Api.Models;
using EmployeeManagement.Models;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using System;
using System.Threading.Tasks;

namespace EmployeeManagement.Api.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class EmployeesController : ControllerBase
    {
        private readonly IEmployeeRepository employeeRepository;

        public EmployeesController(IEmployeeRepository employeeRepository)
        {
            this.employeeRepository = employeeRepository;
        }

        [HttpGet]
        public async Task<ActionResult> GetEmployees()
        {
            try
            {
                return Ok(await employeeRepository.GetEmployees());
            }
            catch (Exception)
            {
                return StatusCode(StatusCodes.Status500InternalServerError,
                    "Error retrieving data from the database");
            }
        }

        [HttpGet("{id:int}")]
        public async Task<ActionResult<Employee>> GetEmployee(int id)
        {
            try
            {
                var result = await employeeRepository.GetEmployee(id);

                if (result == null)
                {
                    return NotFound();
                }

                return result;
            }
            catch (Exception)
            {
                return StatusCode(StatusCodes.Status500InternalServerError,
                    "Error retrieving data from the database");
            }
        }

        [HttpPost]
        public async Task<ActionResult<Employee>> CreateEmployee(Employee employee)
        {
            try
            {
                if(employee == null)
                {
                    return BadRequest();
                } 
                
                var emp = employeeRepository.GetEmployeeByEmail(employee.Email);
                
                if(emp != null)
                {
                    ModelState.AddModelError("email", "Employee email already in use");
                    return BadRequest(ModelState);
                }

                var createdEmployee = await employeeRepository.AddEmployee(employee);

                return CreatedAtAction(nameof(GetEmployee), new { id = createdEmployee.EmployeeId },
                    createdEmployee);
            }
            catch (Exception)
            {
                return StatusCode(StatusCodes.Status500InternalServerError,
                    "Error retrieving data from the database");
            }
        }

        [HttpPut("{id:int}")]
        public async Task<ActionResult<Employee>> UpdateEmployee(int id, Employee employee)
        {
            try
            {
                if(id != employee.EmployeeId)
                {
                    return BadRequest("Employee ID mismatch");
                }

                var employeeToUpdate = await employeeRepository.GetEmployee(id);

                if(employeeToUpdate == null)
                {
                    return NotFound($"Employee with Id = {id} not found");
                }

                return await employeeRepository.UpdateEmployee(employee);
            }
            catch (Exception)
            {
                return StatusCode(StatusCodes.Status500InternalServerError,
                    "Error updating data");
            }
        }

        [HttpDelete("{id:int}")]
        public async Task<ActionResult<Employee>> DeleteEmployee(int id)
        {
            try
            {
                var employeeToDelete = await employeeRepository.GetEmployee(id);

                if (employeeToDelete == null)
                {
                    return NotFound($"Employee with Id = {id} not found");
                }

                return await employeeRepository.DeleteEmployee(id);
            }
            catch (Exception)
            {
                return StatusCode(StatusCodes.Status500InternalServerError,
                    "Error deleting data");
            }
        }
    }
}

EmployeeRepository

EmployeeRepository utilizes a substance structure core to store and recover information from the SQL Server database.

public class EmployeeRepository : IEmployeeRepository
{
    private readonly AppDbContext appDbContext;

    public EmployeeRepository(AppDbContext appDbContext)
    {
        this.appDbContext = appDbContext;
    }
        
    public async Task<Employee> AddEmployee(Employee employee)
    {
        var result = await appDbContext.Employees.AddAsync(employee);
        await appDbContext.SaveChangesAsync();
        return result.Entity;
    }

    public async Task<Employee> DeleteEmployee(int employeeId)
    {
        var result = await appDbContext.Employees
            .FirstOrDefaultAsync(e => e.EmployeeId == employeeId);
        if (result != null)
        {
            appDbContext.Employees.Remove(result);
            await appDbContext.SaveChangesAsync();
            return result;
        }

        return null;
    }

    public async Task<Employee> GetEmployee(int employeeId)
    {
        return await appDbContext.Employees
            .FirstOrDefaultAsync(e => e.EmployeeId == employeeId);
    }

    public async Task<Employee> GetEmployeeByEmail(string email)
    {
        return await appDbContext.Employees
            .FirstOrDefaultAsync(e => e.Email == email);
    }

    public async Task<IEnumerable<Employee>> GetEmployees()
    {
        return await appDbContext.Employees.ToListAsync();
    }

    public async Task<Employee> UpdateEmployee(Employee employee)
    {
        var result = await appDbContext.Employees
            .FirstOrDefaultAsync(e => e.EmployeeId == employee.EmployeeId);

        if (result != null)
        {
            result.FirstName = employee.FirstName;
            result.LastName = employee.LastName;
            result.Email = employee.Email;
            result.DateOfBrith = employee.DateOfBrith;
            result.Gender = employee.Gender;
            result.DepartmentId = employee.DepartmentId;
            result.PhotoPath = employee.PhotoPath;

            await appDbContext.SaveChangesAsync();

            return result;
        }

        return null;
    }
}

Search in ASP.NET Core REST API

Code Explanation

According to the [Route] trait on the EmployeesController, the route to arrive at this regulator is/api/employees

[Route("api/[controller]")]
[ApiController]
public class EmployeesController : ControllerBase
{
}

The accompanying [HttpGet] ascribe indicated an augmentation to the base route/api/employees. So the route to arrive at this Search() strategy is/api/employees/search. The qualities for the two technique boundaries originate from the inquiry strings in the URL.

[HttpGet("{search}")]
public async Task<ActionResult<IEnumerable<Employee>>> Search(string name, Gender? gender)
{
}

On the off chance that you need the inquiry terms (name and sexual orientation) to be incorporated as route boundaries rather than question strings, change the route layout on the HttpGet trait as demonstrated as follows. In any case, this methodology isn't suggested on the off chance that you have many pursuit boundaries.

[HttpGet("{search}/{name}/{gender?}")]
public async Task<ActionResult<IEnumerable<Employee>>> Search(string name, Gender? gender)
{
}

Since the route boundaries and technique boundaries are planned by name, regardless of whether the request doesn't coordinate, they will in any case be effectively planned i.e the URL boundary name is planned to the strategy boundary name and the sex URL boundary is planned to the sex strategy boundary.

[HttpGet("{search}/{name}/{gender?}")]
public async Task<ActionResult<IEnumerable<Employee>>> Search(Gender? gender, string name)
{
}

IEmployeeRepository Interface

public interface IEmployeeRepository
{
    Task<IEnumerable<Employee>> Search(string name, Gender? gender);
}

EmployeeRepository

public class EmployeeRepository : IEmployeeRepository
{
    private readonly AppDbContext appDbContext;

    public EmployeeRepository(AppDbContext appDbContext)
    {
        this.appDbContext = appDbContext;
    }

    public async Task<IEnumerable<Employee>> Search(string name, Gender? gender)
    {
        IQueryable<Employee> query = appDbContext.Employees;
            
        if (!string.IsNullOrEmpty(name))
        {
            query = query.Where(e => e.FirstName.Contains(name)
                        || e.LastName.Contains(name));
        }

        if(gender != null)
        {
            query = query.Where(e => e.Gender == gender);
        }

        return await query.ToListAsync();
    }
}
A to Z Full Forms and Acronyms