Introduction
In this blog, I am going to explain how to do a CRUD Operation with the Latest ANGULAR 20 & for the backend, we are going to use .NET Core Web Api.
Topics to be covered
Setting up an Angular 20 Project with CLI & Creating Components for List, Add, and Edit
Angular Routing for Navigation
Setting Up .NET Core Api (Parody ๐ )
Using Services and Dependency Injection
Components Communicating with APIs and Each Other (subscribe, next, and data binding)
Prerequisites
Before we get started, I assume you already have:
The latest Angular 20 is installed and ready to use.
Prior experience with .NET development , since weโll be building the backend using ASP.NET Core Web API .
Make sure youโre comfortable with VS Code, Visual Studio, and SQL Server โ weโll be using all three.
What we are going to achieve in The End
![AngularCrd]()
Let's Start
Step 1. Setting up an Angular 20 Project with CLI & Creating Components for List, Add, and Edit
Open your terminal and go to your liked folder and write the following commands
ng new NG-CRUD
And then yes to CSS and answer no to any other questions asked
![step1]()
Now open VS Code and this directory where your project is created
-> now open terminal in VS Code and write "ng serve" to run the project, redirect to the URL, and you will see your project runs fine.
We need to create services and components to handle data operations and UI rendering in our Angular application.
Add three components using the following commands "student-list", "student-add", "student-edit".
ng generate component components/student-list --standalone
ng generate component components/student-add --standalone
ng generate component components/student-edit --standalone
![Screenshot 2025-09-06 172710]()
You can find them in the src->app->components folder.
![Screenshot 2025-09-06 172753]()
-> Now we need to add a service that will connect our Angular client to the .NET API
ng generate service services/student
You can review that in src->app->services
-> (OPTIONAL) add Bootstrap for enhanced UI
npm install bootstrap
Then open Angular. Json and replace the style with the following text
"styles": ["node_modules/bootstrap/dist/css/bootstrap.min.css", "src/styles.css"]
![styles]()
Now we are all set up for step 1: Setting up an Angular 20 Project with CLI & Creating Components for List, Add, and Edit
Step 2: Angular Routing for Navigation
-> Routing - Angular Routing allows your app to navigate between different views/components without reloading the page.
In Project find app.routes.ts and add code below.
import { Routes } from '@angular/router';
import { StudentList } from './components/student-list/student-list';
import { StudentAdd } from './components/student-add/student-add';
import { StudentEdit } from './components/student-edit/student-edit';
export const routes: Routes = [
{ path: '', redirectTo: 'students', pathMatch: 'full' },
{ path: 'students', component: StudentList },
{ path: 'students/add', component: StudentAdd },
{ path: 'students/edit/:id', component: StudentEdit },
];
Match your app.route.ts with the below image.
![app3]()
-> next add RouterOutlet & Routerlink in App.html
clean up app.html code and match it with code below
<a routerLink="/students" class="btn btn-secondary">Student List</a>
<a routerLink="/students/add" class="btn btn-success">Add Student</a>
<router-outlet></router-outlet>
![html4]()
-> in app.ts Make sure it imports Routermodule & RouterOutlet
![Screenshot 2025-09-06 202946]()
Your output should look like this - if you click on Student List or Add Student, then you will see a redirection in the URL.
![Screenshot 2025-09-06 202747]()
Step 2 is now all set up: Angular Routing for Navigation
Step 3. Setting Up .NET Core Api (Parody ๐ )
-> for this step, we are first going to make a .NET CORE API project. I promise it's going to be extremely shorter than you expected (Parody ๐)
CREATE DATABASE USERDB
GO
USE USERDB
GO
CREATE TABLE STUDENTS(
ID INT IDENTITY(1,1) PRIMARY KEY,
NAME VARCHAR(50),
CLASS VARCHAR(50)
)
-> Next, adda web api project in Visual Studio and add a connection string in "appsettings.json" as your pc's SQL Server string.
"ConnectionStrings": {
"TempConnection": "Server=LAPTOP-S75MO20E\\MSSQLSERVER01;database=USERDB;TrustServerCertificate=true;Trusted_Connection=true"
}
-> next add a 2-class one for "Student" Model and another for setting up data access, so we name it "Dal"
using System.ComponentModel.DataAnnotations;
namespace AngularBlog
{
public class Students
{
[Key]
public int ID { get; set; }
[Required(ErrorMessage = "Valid Name Required")]
public string Name { get; set; }
[Required(ErrorMessage = "Valid Class Required")]
public string Class { get; set; }
public string? DropDownNAme { get; set; }
}
}
And other
using AngularBlog;
using System.Data.SqlClient;
namespace AngularBlog
{
public class dal
{
private readonly string _Connection;
public dal(IConfiguration configuration)
{
_Connection = configuration.GetConnectionString("TempConnection");
}
public List<Students> GetAll()
{
List<Students> students = new List<Students>();
string Sql = "Select * from Students";
using (SqlConnection con = new SqlConnection(_Connection))
{
con.Open();
var cmd = new SqlCommand(Sql, con);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Students sd = new Students();
sd.ID = Convert.ToInt32(rdr["ID"]);
sd.Name = Convert.ToString(rdr["Name"]);
sd.Class = Convert.ToString(rdr["Class"]);
students.Add(sd);
}
}
return students;
}
public Students GetbyId(int ID)
{
Students sd = new Students();
string Sql = "Select * from Students where ID = @ID";
using (SqlConnection con = new SqlConnection(_Connection))
{
con.Open();
var cmd = new SqlCommand(Sql, con);
cmd.Parameters.AddWithValue("@ID", ID);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
sd.ID = Convert.ToInt32(rdr["ID"]);
sd.Name = Convert.ToString(rdr["Name"]);
sd.Class = Convert.ToString(rdr["Class"]);
}
}
return sd;
}
public bool AddEditUpdte(Students Sd)
{
bool saved = false;
string Sql = @"If Exists(Select * from Students where ID = @ID)
BEGIN
UPDATE Students SET NAME = @NAME, CLASS = @CLASS WHERE ID = @ID
END
ELSE
BEGIN
INSERT INTO STUDENTS (NAME,CLASS) VALUES (@NAME, @CLASS)
END";
using (SqlConnection CON = new SqlConnection(_Connection))
{
CON.Open();
SqlCommand cmd = new SqlCommand(Sql, CON);
cmd.Parameters.AddWithValue("@ID", Sd.ID);
cmd.Parameters.AddWithValue("@NAME", Sd.Name);
cmd.Parameters.AddWithValue("@CLASS", Sd.Class);
saved = cmd.ExecuteNonQuery() > 0;
}
return saved;
}
public List<Students> GetAllDropdown()
{
List<Students> students = new List<Students>();
string Sql = "Select DropName from StudentsDropdown";
using (SqlConnection con = new SqlConnection(_Connection))
{
con.Open();
var cmd = new SqlCommand(Sql, con);
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Students sd = new Students();
sd.DropDownNAme = Convert.ToString(rdr["DropName"]);
students.Add(sd);
}
}
return students;
}
public bool DeleteStudent(int ID)
{
bool saved = false;
string Sql = @"Delete from Students WHERE ID = @ID";
using (SqlConnection CON = new SqlConnection(_Connection))
{
CON.Open();
SqlCommand cmd = new SqlCommand(Sql, CON);
cmd.Parameters.AddWithValue("@ID", ID);
saved = cmd.ExecuteNonQuery() > 0;
}
return saved;
}
}
}
-> after that, add a controller for Angular, or you can just replace its default weather forecast controller with the code below.
using AngularBlog;
using Microsoft.AspNetCore.Mvc;
namespace AngularBlog
{
[ApiController]
[Route("api/[controller]")]
public class AngularController : ControllerBase
{
private readonly dal _dal;
public AngularController(dal dal)
{
_dal = dal;
}
[HttpGet("getall")]
public IActionResult GetAll()
{
var students = _dal.GetAll();
return Ok(students); // returns JSON
}
[HttpGet("{id}")]
public IActionResult GetById(int id)
{
var student = _dal.GetbyId(id);
if (student == null) return NotFound();
return Ok(student);
}
[HttpPost]
public IActionResult AddEdit(Students student)
{
_dal.AddEditUpdte(student);
return Ok(student);
}
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
_dal.DeleteStudent(id);
return NoContent();
}
}
}
Now, at the end, you need to change Program.cs.
using AngularBlog;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
builder.Services.AddScoped<dal>();
builder.Services.AddCors(
options =>
{
options.AddPolicy("AllowAngular", policy =>
{
policy.WithOrigins("http://localhost:4200").AllowAnyHeader().AllowAnyMethod();
});
}
);
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
}
app.UseHttpsRedirection();
app.UseRouting();
app.UseCors("AllowAngular");
app.UseAuthorization();
app.MapControllers();
app.Run();
-> That's it, now run your project and go to this URL or whatever local host your project is on.
https://localhost:7115/api/angular/getall
Now insert some data in the students table, and you will be able to see some Json response containing your records
Step 3 We all set up: Setting Up .NET Core Api (Parody ๐ )
Let's go back to Angular
Step 4. Using Services and Dependency Injection
-> Remember, we created a service at the start of this blog called "Student.ts" ? You can find it inside the service folder now. We are going to implement
Dependency injection there, and going to use it in our project components.
Add code below to your student.ts service.
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs';
export interface Student {
id: number;
name: string;
class: string;
}
@Injectable({ providedIn: 'root' })
export class StudentService {
private apiUrl = 'https://localhost:7115/api/angular'; //adjust port
constructor(private http: HttpClient) { }
// getEmployees(): Observable<Student[]> {
// return this.http.get<Student[]>(this.apiUrl);
// }
getStudents(): Observable<Student[]> {
return this.http.get<Student[]>(`${this.apiUrl}/getall`);
}
getStudentById(id: number): Observable<Student> {
return this.http.get<Student>(`${this.apiUrl}/${id}`);
}
updateStudent(student: Student): Observable<Student> {
return this.http.post<Student>(this.apiUrl, student);
// โก your API uses POST for Add/Edit together
}
addStudent(student: Student): Observable<Student> {
return this.http.post<Student>(this.apiUrl, student);
}
deleteStudent(id: number): Observable<void> {
return this.http.delete<void>(`${this.apiUrl}/${id}`);
}
}
Here, remember to adjust your API URL port according to our web API project, which runs on our local host.
Yes, now our step 4 is completed too
Step 4 Set up completed: Using Services and Dependency Injection
Step 5. Components Communicating with APIs and Each Other (subscribe, next, and data binding)
-> In this project, we have created 3 components "Student-list", "Student-add", "Student-edit"
We will now go to change the content of the student - list. I will show you how to bind data in the student list and how to fetch data from the Service we just created.
-> Navigate to student-list - student-list.ts & add below code there
import { CommonModule } from '@angular/common';
import { Component, signal } from '@angular/core';
import { RouterModule } from '@angular/router';
import { Student, StudentService } from '../../services/student';
@Component({
selector: 'app-student-list',
imports: [CommonModule, RouterModule],
templateUrl: './student-list.html',
styleUrl: './student-list.css'
})
export class StudentList {
students = signal<Student[]>([]);
constructor(private studentService: StudentService) { }
ngOnInit(): void {
this.loadStudents();
}
loadStudents() {
this.studentService.getStudents().subscribe({
next: (data) => this.students.set(data),
error: (err) => console.error("Error Fetching students", err)
});
}
deleteStudent(id: number) {
if (confirm('Are you sure you want to delete this student?')) {
this.studentService.deleteStudent(id).subscribe({
next: () => {
alert('Student deleted successfully!');
this.loadStudents();
},
error: (err) => console.error('error deleting students', err)
})
}
}
}
Now change the code for student-list.html too.
<div class="container mt-4">
<h2>Students List</h2>
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Name</th>
<th>Class</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let s of students()">
<td>{{ s.id }}</td>
<td>{{ s.name }}</td>
<td>{{ s.class }}</td>
<td>
<a [routerLink]="['/students/edit', s.id]" class="btn btn-sm btn-primary">Edit</a>
<button (click)="deleteStudent(s.id)" routerLink="/students" class="btn btn-sm btn-danger">Delete</button>
</td>
</tr>
</tbody>
</table>
</div>
-> now run the project using "ng serve" and make sure your .NET Web API project is running.
You won't see anything except those 2 buttons, but open the console and see the error of missing _httpclient.
![localhost6]()
No worries it's just missing a service called "HttpClient". This service needs to be injected in the root level, so open your main.ts and change your code according to.
import { bootstrapApplication } from '@angular/platform-browser';
import { provideHttpClient } from '@angular/common/http';
import { provideRouter } from '@angular/router';
import { App } from './app/app';
import { routes } from './app/app.routes';
bootstrapApplication(App, {
providers: [
provideRouter(routes),
provideHttpClient()
]
}).catch((err) => console.error(err));
->We add provideHttpClient()
here because HttpClient
is a global provider and needs to be registered at the root level, not inside StudentService
Now open the page, and you will be able to see the lists of students.
![list7]()
Now try clicking on edit. You probably won't see anything on the page, but see in the URL. Our ID is going in it, and next try deleting it will work.
-> Let's move on. Edit article, go to components - student-edit- Student-edit.ts
import { CommonModule } from '@angular/common';
import { Component, OnInit, signal } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { ActivatedRoute, Router, RouterModule } from '@angular/router';
import { Student, StudentService } from '../../services/student';
@Component({
selector: 'app-student-edit',
imports: [CommonModule, FormsModule, RouterModule],
templateUrl: './student-edit.html',
styleUrl: './student-edit.css'
})
export class StudentEdit implements OnInit {
student = signal<Student>({ id: 0, name: '', class: '' });
constructor(private route: ActivatedRoute, private router: Router, private service: StudentService) { }
ngOnInit(): void {
const id = Number(this.route.snapshot.paramMap.get('id'));
if (id) {
this.service.getStudentById(id).subscribe({
next: (data) => this.student.set(data),
error: (err) => console.error('Error loading student', err)
})
}
}
save() {
this.service.updateStudent(this.student()).subscribe({
next: () => {
alert("Student Updated successfully");
this.router.navigate(['/students']);
},
error: (err) => console.error('Error Saving Student', err)
})
}
}
Next, also add Student-edit.html.
<div class="container mt-4">
<h2>Edit Student</h2>
<form (ngSubmit)="save()" #form="ngForm">
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input [(ngModel)]="student().name" name="name" id="name" class="form-control" required />
</div>
<div class="mb-3">
<label for="class" class="form-label">Class</label>
<input [(ngModel)]="student().class" name="class" id="class" class="form-control" required />
</div>
<button type="submit" class="btn btn-success">Save</button>
<a routerLink="/students" class="btn btn-secondary ms-2">Cancel</a>
</form>
</div>
-> Now try to edit, you will be redirected to another page and will be able to edit the data of students successfully.
![edit8]()
In the last we need to add a student-add component, so follow the code below in sequence for student-add.ts & student-add.html.
import { CommonModule } from '@angular/common';
import { Component } from '@angular/core';
import { FormsModule } from '@angular/forms';
import { RouterModule, Router } from '@angular/router';
import { Student, StudentService } from '../../services/student';
@Component({
selector: 'app-student-add',
imports: [CommonModule, FormsModule, RouterModule],
templateUrl: './student-add.html',
styleUrl: './student-add.css'
})
export class StudentAdd {
student: Student = { id: 0, name: '', class: '' };
constructor(private service: StudentService, private router: Router) { }
save() {
this.service.addStudent(this.student).subscribe({
next: () => {
alert('Student added successfully!');
this.router.navigate(['/students']); // back to list
},
error: (err) => console.error('Error adding student', err)
});
}
}
And
<!-- employee-add.html -->
<div class="container mt-4">
<h2>Add Student</h2>
<form (ngSubmit)="save()" #form="ngForm">
<div class="mb-3">
<label for="name" class="form-label">Name</label>
<input [(ngModel)]="student.name" name="name" id="name" class="form-control" required />
</div>
<div class="mb-3">
<label for="class" class="form-label">Class</label>
<input [(ngModel)]="student.class" name="class" id="class" class="form-control" required />
</div>
<button type="submit" class="btn btn-success">Save</button>
<a routerLink="/students" class="btn btn-secondary ms-2">Cancel</a>
</form>
</div>
๐ Summary
So in this article, we actually made a full CRUD app with Angular 20 on the front and .NET Core Web API on the back. First thing we did was spin up an Angular project with CLI and create the basic components โ student list, add, and edit. Then we wired up routing so we can jump between pages easily.
After that, we quickly set up the .NET Core API (told you itโs way shorter than you expect ๐). Then came the important part โ services + dependency injection . Here we also had to fix that _HttpClient
error by adding provideHttpClient()
in main.ts
(not in the service itself, important point).
Finally, we connected everything together: components talking to the API and also to each other using subscribe, next, and data binding .
๐ Just donโt forget to run your Web API project before you test Angular, or nothing will load.
Thatโs it for this CRUD journey. If you followed along, you basically built a full Angular 20 + .NET Core setup. Now itโs your turn to add some spice on top of it. Until next time, keep coding, buddy๐.