This article will explain how to perform CRUD (Create, Read, Update and Delete) operations in Asp.Net Core 3.1 Web API using Entity Framework Core. We will see step-by-step instructions about CRUD operations in Asp.Net Core Web API. We will use the Database First Approach where our database will be ready before creating an actual code.
Before we start, Let's understand the objective of this demonstration which tells what exactly will be covered in this article.
- Create the Database and Tables
- Create Asp.Net Core Web API Project
- Install Nuget Packages for Entity Framework
- Generates Model Classes
- Setup Dependency Injection
- Enable CORS
- Use Swagger
- Create Repository and implement CRUD operations
- Create a Controller and Create API call
So, Let's get started.
Create the Database and Tables
CREATE TABLE [dbo].[Employee](
[EmployeeID] [int] IDENTITY(1,1) NOT NULL,
[EmployeeName] [varchar](500) NULL,
[Department] [varchar](100) NULL,
[EmailId] [nvarchar](500) NULL,
[DOJ] [date] NULL,
CONSTRAINT [PK_Employee] PRIMARY KEY CLUSTERED
(
[EmployeeID] 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
CREATE TABLE [dbo].[Department](
[DepartmentID] [int] IDENTITY(1,1) NOT NULL,
[DepartmentName] [varchar](50) NULL,
CONSTRAINT [PK_Department] PRIMARY KEY CLUSTERED
(
[DepartmentID] 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
Create Asp.Net Core Web API Project
Open Visual studio -> New Project -> ASP.NET Core Web API.
Install Nuget Packages for Entity Framework
- Microsoft.EntityFrameworkCore.
- Microsoft.EntityFrameworkCore.SqlServer
- Microsoft.AspNetCore.Mvc.NewtonsoftJson
- Swashbuckle.AspNetCore
- Microsoft.OpenApi
Now Add Database connection the in appsettings.json file
Generates Model Classes
Now, Create Model Entities
Department
[Table("Department")]
public class Department
{
[Key]
public int DepartmentId { get; set; }
public string DepartmentName { get; set; }
}
Employee
[Table("Employee")]
public class EmployeeAngular
{
[Key]
public int EmployeeID { get; set; }
public string EmployeeName { get; set; }
public string Department { get; set; }
public string EmailId { get; set; }
public DateTime DOJ { get; set; }
}
Now, once we have added our table entities, now we will create APIDbContext Class which will inhert from DbContext class
public class APIDbContext: DbContext {
public APIDbContext(DbContextOptions < APIDbContext > options): base(options) {}
public DbSet < Department > Departments {
get;
set;
}
public DbSet < Employee > Employees {
get;
set;
}
}
Create Repository and implement CRUD operations
Now Create Folder as Repository in which we will write Repository logic which will communicate with database.
Inside Repository folder Create Interface IDepartmentRepository and DepartmentRepository class.
IDepartmentRepository
public interface IDepartmentRepository {
Task < IEnumerable < Department >> GetDepartment();
Task < Department > GetDepartmentByID(int ID);
Task < Department > InsertDepartment(Department objDepartment);
Task < Department > UpdateDepartment(Department objDepartment);
bool DeleteDepartment(int ID);
}
DepartmentRepository
public class DepartmentRepository: IDepartmentRepository {
private readonly APIDbContext _appDBContext;
public DepartmentRepository(APIDbContext context) {
_appDBContext = context ??
throw new ArgumentNullException(nameof(context));
}
public async Task < IEnumerable < Department >> GetDepartment() {
return await _appDBContext.Departments.ToListAsync();
}
public async Task < Department > GetDepartmentByID(int ID) {
return await _appDBContext.Departments.FindAsync(ID);
}
public async Task < Department > InsertDepartment(Department objDepartment) {
_appDBContext.Departments.Add(objDepartment);
await _appDBContext.SaveChangesAsync();
return objDepartment;
}
public async Task < Department > UpdateDepartment(Department objDepartment) {
_appDBContext.Entry(objDepartment).State = EntityState.Modified;
await _appDBContext.SaveChangesAsync();
return objDepartment;
}
public bool DeleteDepartment(int ID) {
bool result = false;
var department = _appDBContext.Departments.Find(ID);
if (department != null) {
_appDBContext.Entry(department).State = EntityState.Deleted;
_appDBContext.SaveChanges();
result = true;
} else {
result = false;
}
return result;
}
}
Same goes for Employee Create Interface IEmployeeRepository and EmployeeRepository class
IEmployeeRepository
public interface IEmployeeRepository {
Task < IEnumerable < Employee >> GetEmployees();
Task < Employee > GetEmployeeByID(int ID);
Task < Employee > InsertEmployee(Employee objEmployee);
Task < Employee > UpdateEmployee(Employee objEmployee);
bool DeleteEmployee(int ID);
}
EmployeeRepository
public class EmployeeRepository: IEmployeeRepository {
private readonly APIDbContext _appDBContext;
public EmployeeRepository(APIDbContext context) {
_appDBContext = context ??
throw new ArgumentNullException(nameof(context));
}
public async Task < IEnumerable < Employee >> GetEmployees() {
return await _appDBContext.Employees.ToListAsync();
}
public async Task < Employee > GetEmployeeByID(int ID) {
return await _appDBContext.Employees.FindAsync(ID);
}
public async Task < Employee > InsertEmployee(Employee objEmployee) {
_appDBContext.Employees.Add(objEmployee);
await _appDBContext.SaveChangesAsync();
return objEmployee;
}
public async Task < Employee > UpdateEmployee(Employee objEmployee) {
_appDBContext.Entry(objEmployee).State = EntityState.Modified;
await _appDBContext.SaveChangesAsync();
return objEmployee;
}
public bool DeleteEmployee(int ID) {
bool result = false;
var department = _appDBContext.Employees.Find(ID);
if (department != null) {
_appDBContext.Entry(department).State = EntityState.Deleted;
_appDBContext.SaveChanges();
result = true;
} else {
result = false;
}
return result;
}
}
Now, Once we are ready with Repository, now lets Setup Dependency Injection
Setup Dependency Injection
Open Startup.cs class file.
services.AddScoped<IDepartmentRepository, DepartmentRepository>();
services.AddScoped<IEmployeeRepository, EmployeeRepository>();
services.AddDbContext<APIDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("EmployeeAppCon")));
Enable CORS
//Enable CORS
services.AddCors(c =>
{
c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin().AllowAnyMethod()
.AllowAnyHeader());
});
app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
Swagger
services.AddSwaggerGen(options => {
options.SwaggerDoc("v1", new OpenApiInfo {
Title = "WEB API",
Version = "v1"
});
});
app.UseSwagger();
app.UseSwaggerUI(c => {
c.SwaggerEndpoint("/swagger/v1/swagger.json", "WEB API");
c.DocumentTitle = "WEB API";
c.DocExpansion(DocExpansion.List);
});
Complete Startup.cs class file code.
public class Startup {
public Startup(IConfiguration configuration) {
Configuration = configuration;
}
public IConfiguration Configuration {
get;
}
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services) {
services.AddScoped < IDepartmentRepository, DepartmentRepository > ();
services.AddScoped < IEmployeeRepository, EmployeeRepository > ();
services.AddDbContext < APIDbContext > (options => options.UseSqlServer(Configuration.GetConnectionString("EmployeeAppCon")));
services.AddSwaggerGen(options => {
options.SwaggerDoc("v1", new OpenApiInfo {
Title = "WEB API",
Version = "v1"
});
});
//Enable CORS
services.AddCors(c => {
c.AddPolicy("AllowOrigin", options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
});
//JSON Serializer
services.AddControllersWithViews().AddNewtonsoftJson(options => options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore).AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new DefaultContractResolver());
services.AddControllers();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env) {
if (env.IsDevelopment()) {
app.UseDeveloperExceptionPage();
}
app.UseCors(options => options.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader());
app.UseHttpsRedirection();
app.UseRouting();
app.UseAuthorization();
app.UseEndpoints(endpoints => {
endpoints.MapControllers();
});
app.UseSwagger();
app.UseSwaggerUI(c => {
c.SwaggerEndpoint("/swagger/v1/swagger.json", "WEB API");
c.DocumentTitle = "WEB API";
c.DocExpansion(DocExpansion.List);
});
app.UseStaticFiles(new StaticFileOptions {
FileProvider = new PhysicalFileProvider(Path.Combine(Directory.GetCurrentDirectory(), "Photos")),
RequestPath = "/Photos"
});
}
}
Note: In Startup.cs class, We have added Dependency Injection, Swagger, and CORS. Also, I have added StaticFiles for the file upload path.
Now let's start creating a Controller
Create a Controller and Create an API call
Department Controller.
[Route("api/[controller]")]
[ApiController]
public class DepartmentController: ControllerBase {
private readonly IDepartmentRepository _department;
public DepartmentController(IDepartmentRepository department) {
_department = department ??
throw new ArgumentNullException(nameof(department));
}
[HttpGet]
[Route("GetDepartment")]
public async Task < IActionResult > Get() {
return Ok(await _department.GetDepartment());
}
[HttpGet]
[Route("GetDepartmentByID/{Id}")]
public async Task < IActionResult > GetDeptById(int Id) {
return Ok(await _department.GetDepartmentByID(Id));
}
[HttpPost]
[Route("AddDepartment")]
public async Task < IActionResult > Post(Department dep) {
var result = await _department.InsertDepartment(dep);
if (result.DepartmentId == 0) {
return StatusCode(StatusCodes.Status500InternalServerError, "Something Went Wrong");
}
return Ok("Added Successfully");
}
[HttpPut]
[Route("UpdateDepartment")]
public async Task < IActionResult > Put(Department dep) {
await _department.UpdateDepartment(dep);
return Ok("Updated Successfully");
}
[HttpDelete]
//[HttpDelete("{id}")]
[Route("DeleteDepartment")]
public JsonResult Delete(int id) {
_department.DeleteDepartment(id);
return new JsonResult("Deleted Successfully");
}
}
Employee Controller
[Route("api/[controller]")]
[ApiController]
public class EmployeeController: ControllerBase {
private readonly IEmployeeRepository _employee;
private readonly IDepartmentRepository _department;
public EmployeeController(IEmployeeRepository employee, IDepartmentRepository department) {
_employee = employee ??
throw new ArgumentNullException(nameof(employee));
_department = department ??
throw new ArgumentNullException(nameof(department));
}
[HttpGet]
[Route("GetEmployee")]
public async Task < IActionResult > Get() {
return Ok(await _employee.GetEmployees());
}
[HttpGet]
[Route("GetEmployeeByID/{Id}")]
public async Task < IActionResult > GetEmpByID(int Id) {
return Ok(await _employee.GetEmployeeByID(Id));
}
[HttpPost]
[Route("AddEmployee")]
public async Task < IActionResult > Post(Employee emp) {
var result = await _employee.InsertEmployee(emp);
if (result.EmployeeID == 0) {
return StatusCode(StatusCodes.Status500InternalServerError, "Something Went Wrong");
}
return Ok("Added Successfully");
}
[HttpPut]
[Route("UpdateEmployee")]
public async Task < IActionResult > Put(Employee emp) {
await _employee.UpdateEmployee(emp);
return Ok("Updated Successfully");
}
[HttpDelete]
[Route("DeleteEmployee")]
//[HttpDelete("{id}")]
public JsonResult Delete(int id) {
var result = _employee.DeleteEmployee(id);
return new JsonResult("Deleted Successfully");
}
[Route("SaveFile")]
[HttpPost]
public JsonResult SaveFile()
{
try
{
var httpRequest = Request.Form;
var postedFile = httpRequest.Files[0];
string filename = postedFile.FileName;
var physicalPath = _env.ContentRootPath + "/Photos/" + filename;
using (var stream = new FileStream(physicalPath, FileMode.Create))
{
stream.CopyTo(stream);
}
return new JsonResult(filename);
}
catch (Exception)
{
return new JsonResult("anonymous.png");
}
}
[HttpGet]
[Route("GetDepartment")]
public async Task < IActionResult > GetAllDepartmentNames() {
return Ok(await _department.GetDepartment());
}
}
Now Run the Project using F5
Get All Department
Get Department By Id
Add Department
In Database
Update Department
In Database
Delete Department
In Database
Now, the Same we can try for Employee.
I have added the full code as an attachment.
Note: We can use this web API for angular and react js curd demo.