Loading, please wait...

A to Z Full Forms and Acronyms

POST and PUT in ASP.NET Core REST API

In this article we will discuss, how to create a new item, i.e implement Http post in ASP.NET Core REST API and also how to update an existing resource, i.e implement HTTP PUT in ASP.NET Core REST API.

Post in ASP.NET Core REST API

To create another thing, issue an HTTP POST solicitation to the URI/programming interface/employees. Posting to the assortment/programming interface/employees bodes well due to the assortment of employees we need to include another employee.

ASP.NET Core REST API - HTTP POST Example

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

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

    [HttpPost]
    public async Task<ActionResult<Employee>> CreateEmployee(Employee employee)
    {
        try
        {
            if (employee == null)
                return BadRequest();

            var createdEmployee = await employeeRepository.AddEmployee(employee);

            return CreatedAtAction(nameof(GetEmployee),
                new { id = createdEmployee.EmployeeId }, createdEmployee);
        }
        catch (Exception)
        {
            return StatusCode(StatusCodes.Status500InternalServerError,
                "Error creating new employee record");
        }
    }
}

Code Explanation

It is the POST demand that is utilized to create another asset, for our situation another representative. This is the explanation CreateEmployee() strategy is beautified with the HttpPost characteristic. EmployeesController class is finished with ApiController quality. This trait permits the information from the solicitation to be planned to the worker boundary on CreateEmployee() strategy.

Either this ApiController property is required or the technique boundary must be embellished with [FromBody] characteristic. Something else, the model restricting won't fill in true to form and the worker information from the solicitation won't be planned to the representative boundary on the CreateEmployee strategy.

[HttpPost]
public async Task<IActionResult> CreateEmployee([FromBody]Employee employee)
{
}

The infused EmployeeRepository occasion adds the new representative to the SQL Server database.

var createdEmployee = await employeeRepository.AddEmployee(employee);

At the point when another asset is created the accompanying 3 things generally occur

Return the HTTP status code 201 to show that the asset is effectively created.

Return the recently created asset. For our situation, the recently created representative.

Add a Location header to the reaction. The Location header indicates the URI of the recently created worker object.

When a new resource is created the following over three things. We are utilizing the nameof administrator as opposed to including the technique name (GetEmployee) in a string.

return CreatedAtAction(nameof(GetEmployee),
    new { id = createdEmployee.EmployeeId }, createdEmployee);

This is a decent practice provided that we later change the name of the technique and neglect to transform it here, the compiler will create a blunder. In the solicitation body, in the event that we do exclude an incentive for a particular property of the worker. That property will be set to invalid or default esteem contingent upon the datatype.

In the solicitation body, on the off chance that we incorporate a property that doesn't exist in the representative article, it will be lost. This is the conduct we need. On the off chance that the solicitation incorporates superfluous or extra information, basically disregard it.

Complete REST API Controller Code

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([FromBody]Employee employee)
        {
            try
            {
                if (employee == null)
                    return BadRequest();

                var createdEmployee = await employeeRepository.AddEmployee(employee);

                return CreatedAtAction(nameof(GetEmployee),
                    new { id = createdEmployee.EmployeeId }, createdEmployee);
            }
            catch (Exception)
            {
                return StatusCode(StatusCodes.Status500InternalServerError,
                    "Error creating new employee record");
            }
        }
    }
}

Put in ASP.NET Core REST API

To refresh a current thing, issue an HTTP PUT solicitation to the URI/api/employees/ID. The ID of the representative to refresh must be passed in the URI.

ASP.NET Core REST API - HTTP PUT Example

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

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

    [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");
        }
    }
}

Code Explanation

It is the PUT demand that is utilized to refresh a current worker. This is the explanation UpdateEmployee() technique is adorned with the HttpPut property. EmployeesController class is enlivened with ApiController characteristic. This quality permits the information from the solicitation to be planned to the worker boundary on UpdateEmployee() technique.

Either this ApiController characteristic is required or the strategy boundary must be designed with [FromBody] trait. Something else, the model restricting won't function true to form and the worker information from the solicitation won't be planned to the representative boundary on the UpdateEmployee strategy.

[HttpPut]
public async Task<IActionResult> UpdateEmployee(int id, [FromBody]Employee employee)
{
}

The HttpPut characteristic on UpdateEmployee() technique additionally has a course format. The id of the worker will be attached to the URL/api/employees. So the URL becomes/api/employees/5

[HttpPut("{id:int}")]
public async Task<ActionResult<Employee>> UpdateEmployee(int id, Employee employee)

The employee id esteem in the URL is consequently planned to the id boundary on the UpdateEmployee(int id, Employee representative) technique. As we are utilizing the int course imperative on the id course boundary, the id esteem in the URL is planned to the technique boundary, just if the worth is a number.

Complete EmployeeController Code

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 creating employee");
            }
        }

        [HttpPut("{id}")]
        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");
            }
        }
    }
}
A to Z Full Forms and Acronyms