Introduction
Building a simple CRUD application is one of the best ways to understand how all layers of a full-stack application work together. CRUD stands for Create, Read, Update, and Delete. In this tutorial, we will build a complete CRUD system using:
Angular as the frontend
ASP.NET Core Web API as the backend
SQL Server as the database
This guide walks you step-by-step through the entire setup: database design, API development, Angular UI, service integration, and testing CRUD operations.
Application Architecture Overview
The full-stack flow looks like this:
Angular UI → Angular Service → ASP.NET Core API → EF Core → SQL Server
↑ ↓
←————— JSON Response ←————————— API Controller ←—————————
Each layer has a clear responsibility:
SQL Server stores the data
Entity Framework Core manages the ORM
ASP.NET Core exposes APIs
Angular interacts with the API and displays UI
1. Setting Up the Database
Create the SQL Table
We will build a simple "Employees" CRUD system.
Run this SQL script:
CREATE TABLE Employees (
Id INT IDENTITY(1,1) PRIMARY KEY,
Name NVARCHAR(100),
Email NVARCHAR(100),
Department NVARCHAR(50)
);
This table will store our data.
2. Building the ASP.NET Core API
Create a New Project
Run:
dotnet new webapi -n CrudApi
cd CrudApi
Add Entity Framework Core and SQL Server Provider
Install packages:
dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
Create the DB Context
Create AppDbContext.cs:
using Microsoft.EntityFrameworkCore;
namespace CrudApi.Data
{
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options) { }
public DbSet<Employee> Employees { get; set; }
}
}
Create Employee Model
Create Employee.cs:
namespace CrudApi.Models
{
public class Employee
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Department { get; set; }
}
}
Add Connection String in appsettings.json
"ConnectionStrings": {
"DefaultConnection": "Server=YOUR_SERVER;Database=CrudDb;Trusted_Connection=True;TrustServerCertificate=True;"
}
Register SQL Server in Program.cs
builder.Services.AddDbContext<AppDbContext>(
options => options.UseSqlServer(builder.Configuration.GetConnectionString("DefaultConnection"))
);
Create the CRUD Controller
Create EmployeesController.cs:
[ApiController]
[Route("api/[controller]")]
public class EmployeesController : ControllerBase
{
private readonly AppDbContext _context;
public EmployeesController(AppDbContext context)
{
_context = context;
}
// GET All
[HttpGet]
public async Task<IActionResult> Get()
{
return Ok(await _context.Employees.ToListAsync());
}
// GET by Id
[HttpGet("{id}")]
public async Task<IActionResult> Get(int id)
{
var emp = await _context.Employees.FindAsync(id);
return emp == null ? NotFound() : Ok(emp);
}
// POST Create
[HttpPost]
public async Task<IActionResult> Post(Employee emp)
{
_context.Employees.Add(emp);
await _context.SaveChangesAsync();
return Ok(emp);
}
// PUT Update
[HttpPut("{id}")]
public async Task<IActionResult> Put(int id, Employee emp)
{
var dbEmp = await _context.Employees.FindAsync(id);
if (dbEmp == null) return NotFound();
dbEmp.Name = emp.Name;
dbEmp.Email = emp.Email;
dbEmp.Department = emp.Department;
await _context.SaveChangesAsync();
return Ok(dbEmp);
}
// DELETE
[HttpDelete("{id}")]
public async Task<IActionResult> Delete(int id)
{
var emp = await _context.Employees.FindAsync(id);
if (emp == null) return NotFound();
_context.Employees.Remove(emp);
await _context.SaveChangesAsync();
return Ok();
}
}

Join the conversation! Your thoughts help the community grow.