2024: A Landmark Year for Global Crypto Regulation
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
Nitin Pandit

Nitin Pandit

With over 10 years of vast development experience with different technologies, Nitin Pandit is Microsoft certified Most Valued Professional (Microsoft MVP) with a rich skillset that includes developing and managing IT/Web-based applications in different technologies, such as – C#.NET, ADO.NET, LINQ to SQL, WCF, and ASP.NET 2.0/3.x/4.0, WCF, WPF, MVC 5.0 (Razor), and Silverlight, along with client-side programming techniques, like jQuery and AngularJS. Nitin possesses a Master’s degree in Computer Science and has been actively contributing to the development community for its betterment. He has written more than 100 blogs/articles and 3 eBooks on different technologies to help improve the knowledge of young technology professionals. He has trained more than one lakh students and professionals, as a speaker in workshops and AppFests, conducted in more than 25 universities in North India.

Related Article

Cookies.

By using this website, you automatically accept that we use cookies. What for?

Understood