CRUD Operations With ASP.NET Core Using Angular 5 And ADO.NET

Introduction

In this article, I am going to explain how to create an MVC web application in ASP.NET Core 2.0 with Angular 5. We will be creating a sample Employee Record Management system using Angular 5 at frontend, Web API on backend and ADO.NET to fetch data from the database. We will use an Angular form with required field validations for the input fields to get data from the user.

We will be using Visual Studio 2017 (Version 15.3.5 or above) and SQL Server 2008.

Prerequisites

  • Install .NET Core 2.0.0 or above SDK from here.
  • Install Visual Studio 2017 Community Edition (Version 15.3.5 or above) from here.
  • Download and install the latest version of Node.js from here.

Source Code

Before proceeding I would recommend you to get the source code from GitHub.

Now let’s proceed to create our tables and stored procedures using SQL Server. I am using SQL server 2008. You can use any version above that also.

Creating Table and Stored Procedures

We will be using a DB table to store all the records of employees.

Open SQL Server and use the following script to create tblEmployee table.

  1. Create table tblEmployee(      
  2.     EmployeeId int IDENTITY(1,1) NOT NULL,      
  3.     Name varchar(20) NOT NULL,      
  4.     City varchar(20) NOT NULL,      
  5.     Department varchar(20) NOT NULL,      
  6.     Gender varchar(6) NOT NULL      
  7. )   

Now, we will create stored procedures to add, delete, update, and get employee data.

To insert an Employee Record

  1. Create procedure spAddEmployee         
  2. (        
  3.     @Name VARCHAR(20),         
  4.     @City VARCHAR(20),        
  5.     @Department VARCHAR(20),        
  6.     @Gender VARCHAR(6)        
  7. )        
  8. as         
  9. Begin         
  10.     Insert into tblEmployee (Name,City,Department, Gender)         
  11.     Values (@Name,@City,@Department, @Gender)         
  12. End  
To update an Employee Record
  1. Create procedure spUpdateEmployee        
  2. (        
  3.    @EmpId INTEGER ,      
  4.    @Name VARCHAR(20),       
  5.    @City VARCHAR(20),      
  6.    @Department VARCHAR(20),      
  7.    @Gender VARCHAR(6)      
  8. )        
  9. as        
  10. begin        
  11.    Update tblEmployee         
  12.    set Name=@Name,        
  13.    City=@City,        
  14.    Department=@Department,      
  15.    Gender=@Gender        
  16.    where EmployeeId=@EmpId        
  17. End   
To delete an Employee Record
  1. Create procedure spDeleteEmployee       
  2. (        
  3.    @EmpId int        
  4. )        
  5. as         
  6. begin        
  7.    Delete from tblEmployee where EmployeeId=@EmpId        
  8. End  
To view all Employee Records
  1. Create procedure spGetAllEmployees      
  2. as      
  3. Begin      
  4.     select *      
  5.     from tblEmployee   
  6.     order by EmployeeId      
  7. End  
Now, our Database part has been completed. So, we will proceed to create the MVC application using Visual Studio 2017.

Create MVC Web Application

Open Visual Studio and select File >> New >> Project



After selecting the project, a "New Project" dialog will open. Select .NET Core inside Visual C# menu from the left panel.

Then, select “ASP.NET Core Web Application” from available project types. Put the name of the project as ASPCoreWithAngular and press OK. Refer to the image below.



After clicking on OK, a new dialog will open asking to select the project template. You can observe two drop-down menus at the top left of the template window. Select “.NET Core” and “ASP.NET Core 2.0” from these dropdowns. Then, select “Angular” template and press OK.



Now, our project will be created. You can observe the folder structure in solution explorer as shown in below image.



Here we have our Controllers and Views folders. We won’t be touching the Views folders for this tutorial since we will be using Angular to handle the UI. The Controllers folders will contain our Web API Controller. The point of interest for us is the ClientApp folder where client side of our application resides. Inside the ClientApp/app/components folder, we already have few components created which are provided by default with the Angular template in VS 2017. These components won’t affect our application, but for the sake of this tutorial, we will delete fetchdata and counter folders from ClientApp/app/components.

Adding the Model to the Application

You can also observe that there is no Models folder in our application. So, we will create one by Right-click on the solution name and then Add >> New Folder and name the folder as Models.



Right click on Models folder and select Add >> Class. Name your class Employee.cs. This class will contain our Employee model properties.

Add one more class file to Models folder. Name it as EmployeeDataAccessLayer.cs . This class will contain our Database related operations.

Now, the Models folder has the following structure.


Open Employee.cs and put the following code in it. This is our Employee class having five properties of Employees.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Threading.Tasks;  
  5.   
  6. namespace ASPCoreWithAngular.Models  
  7. {  
  8.     public class Employee  
  9.     {  
  10.         public int ID { getset; }  
  11.   
  12.         public string Name { getset; }  
  13.   
  14.         public string Gender { getset; }  
  15.   
  16.         public string Department { getset; }  
  17.   
  18.         public string City { getset; }  
  19.     }  
  20. }  
Open EmployeeDataAccessLayer.cs and put the following code to handle database operations. Make sure to put your connection string.
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Data;  
  4. using System.Data.SqlClient;  
  5. using System.Linq;  
  6. using System.Threading.Tasks;  
  7.   
  8. namespace ASPCoreWithAngular.Models  
  9. {  
  10.     public class EmployeeDataAccessLayer  
  11.     {  
  12.         string connectionString = "Put Your Connection string here";  
  13.   
  14.         //To View all employees details  
  15.         public IEnumerable<Employee> GetAllEmployees()  
  16.         {  
  17.             try  
  18.             {  
  19.                 List<Employee> lstemployee = new List<Employee>();  
  20.   
  21.                 using (SqlConnection con = new SqlConnection(connectionString))  
  22.                 {  
  23.                     SqlCommand cmd = new SqlCommand("spGetAllEmployees", con);  
  24.                     cmd.CommandType = CommandType.StoredProcedure;  
  25.   
  26.                     con.Open();  
  27.                     SqlDataReader rdr = cmd.ExecuteReader();  
  28.   
  29.                     while (rdr.Read())  
  30.                     {  
  31.                         Employee employee = new Employee();  
  32.   
  33.                         employee.ID = Convert.ToInt32(rdr["EmployeeID"]);  
  34.                         employee.Name = rdr["Name"].ToString();  
  35.                         employee.Gender = rdr["Gender"].ToString();  
  36.                         employee.Department = rdr["Department"].ToString();  
  37.                         employee.City = rdr["City"].ToString();  
  38.   
  39.                         lstemployee.Add(employee);  
  40.                     }  
  41.                     con.Close();  
  42.                 }  
  43.                 return lstemployee;  
  44.             }  
  45.             catch  
  46.             {  
  47.                 throw;  
  48.             }  
  49.         }  
  50.   
  51.         //To Add new employee record   
  52.         public int AddEmployee(Employee employee)  
  53.         {  
  54.             try  
  55.             {  
  56.                 using (SqlConnection con = new SqlConnection(connectionString))  
  57.                 {  
  58.                     SqlCommand cmd = new SqlCommand("spAddEmployee", con);  
  59.                     cmd.CommandType = CommandType.StoredProcedure;  
  60.   
  61.                     cmd.Parameters.AddWithValue("@Name", employee.Name);  
  62.                     cmd.Parameters.AddWithValue("@Gender", employee.Gender);  
  63.                     cmd.Parameters.AddWithValue("@Department", employee.Department);  
  64.                     cmd.Parameters.AddWithValue("@City", employee.City);  
  65.   
  66.                     con.Open();  
  67.                     cmd.ExecuteNonQuery();  
  68.                     con.Close();  
  69.                 }  
  70.                 return 1;  
  71.             }  
  72.             catch  
  73.             {  
  74.                 throw;  
  75.             }  
  76.         }  
  77.   
  78.         //To Update the records of a particluar employee  
  79.         public int UpdateEmployee(Employee employee)  
  80.         {  
  81.             try  
  82.             {  
  83.                 using (SqlConnection con = new SqlConnection(connectionString))  
  84.                 {  
  85.                     SqlCommand cmd = new SqlCommand("spUpdateEmployee", con);  
  86.                     cmd.CommandType = CommandType.StoredProcedure;  
  87.   
  88.                     cmd.Parameters.AddWithValue("@EmpId", employee.ID);  
  89.                     cmd.Parameters.AddWithValue("@Name", employee.Name);  
  90.                     cmd.Parameters.AddWithValue("@Gender", employee.Gender);  
  91.                     cmd.Parameters.AddWithValue("@Department", employee.Department);  
  92.                     cmd.Parameters.AddWithValue("@City", employee.City);  
  93.   
  94.                     con.Open();  
  95.                     cmd.ExecuteNonQuery();  
  96.                     con.Close();  
  97.                 }  
  98.                 return 1;  
  99.             }  
  100.             catch  
  101.             {  
  102.                 throw;  
  103.             }  
  104.         }  
  105.   
  106.         //Get the details of a particular employee  
  107.         public Employee GetEmployeeData(int id)  
  108.         {  
  109.             try  
  110.             {  
  111.                 Employee employee = new Employee();  
  112.   
  113.                 using (SqlConnection con = new SqlConnection(connectionString))  
  114.                 {  
  115.                     string sqlQuery = "SELECT * FROM tblEmployee WHERE EmployeeID= " + id;  
  116.                     SqlCommand cmd = new SqlCommand(sqlQuery, con);  
  117.   
  118.                     con.Open();  
  119.                     SqlDataReader rdr = cmd.ExecuteReader();  
  120.   
  121.                     while (rdr.Read())  
  122.                     {  
  123.                         employee.ID = Convert.ToInt32(rdr["EmployeeID"]);  
  124.                         employee.Name = rdr["Name"].ToString();  
  125.                         employee.Gender = rdr["Gender"].ToString();  
  126.                         employee.Department = rdr["Department"].ToString();  
  127.                         employee.City = rdr["City"].ToString();  
  128.                     }  
  129.                 }  
  130.                 return employee;  
  131.             }  
  132.             catch  
  133.             {  
  134.                 throw;  
  135.             }  
  136.         }  
  137.   
  138.         //To Delete the record on a particular employee  
  139.         public int DeleteEmployee(int id)  
  140.         {  
  141.             try  
  142.             {  
  143.                 using (SqlConnection con = new SqlConnection(connectionString))  
  144.                 {  
  145.                     SqlCommand cmd = new SqlCommand("spDeleteEmployee", con);  
  146.                     cmd.CommandType = CommandType.StoredProcedure;  
  147.   
  148.                     cmd.Parameters.AddWithValue("@EmpId", id);  
  149.   
  150.                     con.Open();  
  151.                     cmd.ExecuteNonQuery();  
  152.                     con.Close();  
  153.                 }  
  154.                 return 1;  
  155.             }  
  156.             catch  
  157.             {  
  158.                 throw;  
  159.             }  
  160.         }  
  161.     }  
  162. }  

Now, we will proceed to create our Web Api Controller.

Adding the Web API Controller to the Application

Right click on Controllers folder and select Add >> New Item



An “Add New Item” dialog box will open. Select ASP.NET from the left panel, then select “Web API Controller Class” from templates panel, and put the name as EmployeeController.cs. Click Add.

This will create our Web API EmployeeController class. We will put all our business logic in this controller. We will call the methods of EmployeeDataAccessLayer to fetch data and pass on the data to Angular frontend.

Open EmployeeController.cs file and put the following code into it
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Threading.Tasks;  
  5. using Microsoft.AspNetCore.Mvc;  
  6. using System.Data.SqlClient;  
  7. using System.Data;  
  8. using ASPCoreWithAngular.Models;  
  9.   
  10. namespace ASPCoreWithAngular.Controllers  
  11. {  
  12.     public class EmployeeController : Controller  
  13.     {  
  14.         EmployeeDataAccessLayer objemployee = new EmployeeDataAccessLayer();  
  15.   
  16.         [HttpGet]  
  17.         [Route("api/Employee/Index")]  
  18.         public IEnumerable<Employee> Index()  
  19.         {  
  20.             return objemployee.GetAllEmployees();  
  21.         }  
  22.   
  23.         [HttpPost]  
  24.         [Route("api/Employee/Create")]  
  25.         public int Create([FromBody] Employee employee)  
  26.         {  
  27.             return objemployee.AddEmployee(employee);  
  28.         }  
  29.   
  30.         [HttpGet]  
  31.         [Route("api/Employee/Details/{id}")]  
  32.         public Employee Details(int id)  
  33.         {  
  34.             return objemployee.GetEmployeeData(id);  
  35.         }  
  36.   
  37.         [HttpPut]  
  38.         [Route("api/Employee/Edit")]  
  39.         public int Edit([FromBody]Employee employee)  
  40.         {  
  41.             return objemployee.UpdateEmployee(employee);  
  42.         }  
  43.   
  44.         [HttpDelete]  
  45.         [Route("api/Employee/Delete/{id}")]  
  46.         public int Delete(int id)  
  47.         {  
  48.             return objemployee.DeleteEmployee(id);  
  49.         }  
  50.     }  
  51. }  

We are done with our backend logic. So, we will now proceed to code our frontend using Angular 5.

Create the Angular Service

We will create an Angular service which will convert the Web API response to JSON and pass it to our component

Right click on ClientApp/app folder and then Add >> New Folder and name the folder as Services.

Right click on Sevices folder and select Add >> New Item. An “Add New Item” dialog box will open. Select Scripts from the left panel, then select “TypeScript File” from templates panel, and put the name as empservice.service.ts. Click Add



Open empservice.service.ts file and put the following code into it
  1. import { Injectable, Inject } from '@angular/core';  
  2. import { Http, Response } from '@angular/http';  
  3. import { Observable } from 'rxjs/Observable';  
  4. import { Router } from '@angular/router';  
  5. import 'rxjs/add/operator/map';  
  6. import 'rxjs/add/operator/catch';  
  7. import 'rxjs/add/observable/throw';  
  8.   
  9. @Injectable()  
  10. export class EmployeeService {  
  11.     myAppUrl: string = "";  
  12.   
  13.     constructor(private _http: Http, @Inject('BASE_URL') baseUrl: string) {  
  14.         this.myAppUrl = baseUrl;  
  15.     }  
  16.   
  17.     getEmployees() {  
  18.         return this._http.get(this.myAppUrl + 'api/Employee/Index')  
  19.             .map((response: Response) => response.json())  
  20.             .catch(this.errorHandler);  
  21.     }  
  22.   
  23.     getEmployeeById(id: number) {  
  24.         return this._http.get(this.myAppUrl + "api/Employee/Details/" + id)  
  25.             .map((response: Response) => response.json())  
  26.             .catch(this.errorHandler)  
  27.     }  
  28.   
  29.     saveEmployee(employee) {  
  30.         return this._http.post(this.myAppUrl + 'api/Employee/Create', employee)  
  31.             .map((response: Response) => response.json())  
  32.             .catch(this.errorHandler)  
  33.     }  
  34.   
  35.     updateEmployee(employee) {  
  36.         return this._http.put(this.myAppUrl + 'api/Employee/Edit', employee)  
  37.             .map((response: Response) => response.json())  
  38.             .catch(this.errorHandler);  
  39.     }  
  40.   
  41.     deleteEmployee(id) {  
  42.         return this._http.delete(this.myAppUrl + "api/Employee/Delete/" + id)  
  43.             .map((response: Response) => response.json())  
  44.             .catch(this.errorHandler);  
  45.     }  
  46.   
  47.     errorHandler(error: Response) {  
  48.         console.log(error);  
  49.         return Observable.throw(error);  
  50.     }  
  51. }  

At this point of time, you might get an error “Parameter 'employee' implicitly has an 'any' type” in empservice.service.ts file.

If your encounter this issue then add the following line inside tsconfig.json file

"noImplicitAny": false

Refer to below image,

Now we will proceed to create our components.

Creating Angular Components

We will be adding two Angular components to our application

  • fetchemployee component - to display all the employee data and delete an existing employee data
  • addemployee component - to add a new employee data as well as to edit an existing employee data.
Right click on ClientApp/app/components folder and select Add >> New Folder and name the folder as addemployee. Right click on addemployee folder and select Add >> New Item. An “Add New Item” dialog box will open. Select Web from the left panel, then select “TypeScript File” from templates panel, and put the name as Addemployee.component.ts. Click Add. This will add a typescript file inside addemployee folder



Right click on addemployee folder and select Add >> New Item. An “Add New Item” dialog box will open. Select ASP.NET Core from the left panel, then select “HTML Page” from templates panel, and put the name as Addemployee.component.html. Click Add. This will add a HTML file inside addemployee folder.

Similarly add fetchemployee.component.ts typescript and fetchemployee.component.html HTML file inside fetchemployee folder.

Now our ClientApp/app/components will look like the image below,



Open fetchemployee.component.ts file and put the following code into it
  1. import { Component, Inject } from '@angular/core';  
  2. import { Http, Headers } from '@angular/http';  
  3. import { Router, ActivatedRoute } from '@angular/router';  
  4. import { EmployeeService } from '../../services/empservice.service'  
  5.   
  6. @Component({  
  7.     selector: 'fetchemployee',  
  8.     templateUrl: './fetchemployee.component.html'  
  9. })  
  10.   
  11. export class FetchEmployeeComponent {  
  12.     public empList: EmployeeData[];  
  13.   
  14.     constructor(public http: Http, private _router: Router, private _employeeService: EmployeeService) {  
  15.         this.getEmployees();  
  16.     }  
  17.   
  18.     getEmployees() {  
  19.         this._employeeService.getEmployees().subscribe(  
  20.             data => this.empList = data  
  21.         )  
  22.     }  
  23.   
  24.     delete(employeeID) {  
  25.         var ans = confirm("Do you want to delete customer with Id: " + employeeID);  
  26.         if (ans) {  
  27.             this._employeeService.deleteEmployee(employeeID).subscribe((data) => {  
  28.                 this.getEmployees();  
  29.             }, error => console.error(error))   
  30.         }  
  31.     }  
  32. }  
  33.   
  34. interface EmployeeData {  
  35.     id: number;  
  36.     name: string;  
  37.     gender: string;  
  38.     department: string;  
  39.     city: string;  
  40. }  

Let’s understand this code. At the very top we have imported Angular modules and EmployeeService references. After this we have @Component decorator to define the selector and template URL for our component

Inside the FetchEmployeeComponent class we have declared an array variable empList of type EmployeeData where EmployeeData is an interface having the properties same as our Employee Model class. Inside the getEmployees method we are calling the getEmployees method of our service EmployeeService, which will return an array of Employees to be stored in empList variable. The getEmployees method is called inside the constructor so that the employee data will be displayed as the page loads.

Next, we have delete method which accepts employeeID as parameter. This will prompt the user with a confirmation box and if the user selects yes then it will delete the employee with this employeeID.

Open fetchemployee.component.html file and paste the following code to it
  1. <h1>Employee Data</h1>  
  2.   
  3. <p>This component demonstrates fetching Employee data from the server.</p>  
  4.   
  5. <p *ngIf="!empList"><em>Loading...</em></p>  
  6.   
  7. <p>  
  8.     <a [routerLink]="['/register-employee']">Create New</a>  
  9. </p>  
  10.   
  11. <table class='table' *ngIf="empList">  
  12.     <thead>  
  13.         <tr>  
  14.             <th>ID</th>  
  15.             <th>Name</th>  
  16.             <th>Gender</th>  
  17.             <th>Department</th>  
  18.             <th>City</th>  
  19.         </tr>  
  20.     </thead>  
  21.     <tbody>  
  22.         <tr *ngFor="let emp of empList">  
  23.             <td>{{ emp.id }}</td>  
  24.             <td>{{ emp.name }}</td>  
  25.             <td>{{ emp.gender }}</td>  
  26.             <td>{{ emp.department }}</td>  
  27.             <td>{{ emp.city }}</td>  
  28.             <td>  
  29.             <td>  
  30.                 <a [routerLink]="['/employee/edit/', emp.id]">Edit</a> |  
  31.                 <a [routerLink]="" (click)="delete(emp.id)">Delete</a>  
  32.             </td>  
  33.         </tr>  
  34.     </tbody>  
  35. </table>  

The code for this html file is pretty simple. On the top it has a link to create new employee record and after that it will have a table to display employee data and two link for editing and deleting each employee record.

Now open Addemployee.component.ts file and put the following code into it.
  1. import { Component, OnInit } from '@angular/core';  
  2. import { Http, Headers } from '@angular/http';  
  3. import { NgForm, FormBuilder, FormGroup, Validators, FormControl } from '@angular/forms';  
  4. import { Router, ActivatedRoute } from '@angular/router';  
  5. import { FetchEmployeeComponent } from '../fetchemployee/fetchemployee.component';  
  6. import { EmployeeService } from '../../services/empservice.service';  
  7.   
  8. @Component({  
  9.     selector: 'createemployee',  
  10.     templateUrl: './AddEmployee.component.html'  
  11. })  
  12.   
  13. export class createemployee implements OnInit {  
  14.     employeeForm: FormGroup;  
  15.     title: string = "Create";  
  16.     id: number;  
  17.     errorMessage: any;  
  18.   
  19.     constructor(private _fb: FormBuilder, private _avRoute: ActivatedRoute,  
  20.         private _employeeService: EmployeeService, private _router: Router) {  
  21.         if (this._avRoute.snapshot.params["id"]) {  
  22.             this.id = this._avRoute.snapshot.params["id"];  
  23.         }  
  24.   
  25.         this.employeeForm = this._fb.group({  
  26.             id: 0,  
  27.             name: ['', [Validators.required]],  
  28.             gender: ['', [Validators.required]],  
  29.             department: ['', [Validators.required]],  
  30.             city: ['', [Validators.required]]  
  31.         })  
  32.     }  
  33.   
  34.     ngOnInit() {  
  35.         if (this.id > 0) {  
  36.             this.title = "Edit";  
  37.             this._employeeService.getEmployeeById(this.id)  
  38.                 .subscribe(resp => this.employeeForm.setValue(resp)  
  39.                 , error => this.errorMessage = error);  
  40.         }  
  41.     }  
  42.   
  43.     save() {  
  44.   
  45.         if (!this.employeeForm.valid) {  
  46.             return;  
  47.         }  
  48.   
  49.         if (this.title == "Create") {  
  50.             this._employeeService.saveEmployee(this.employeeForm.value)  
  51.                 .subscribe((data) => {  
  52.                     this._router.navigate(['/fetch-employee']);  
  53.                 }, error => this.errorMessage = error)  
  54.         }  
  55.         else if (this.title == "Edit") {  
  56.             this._employeeService.updateEmployee(this.employeeForm.value)  
  57.                 .subscribe((data) => {  
  58.                     this._router.navigate(['/fetch-employee']);  
  59.                 }, error => this.errorMessage = error)   
  60.         }  
  61.     }  
  62.   
  63.     cancel() {  
  64.         this._router.navigate(['/fetch-employee']);  
  65.     }  
  66.   
  67.     get name() { return this.employeeForm.get('name'); }  
  68.     get gender() { return this.employeeForm.get('gender'); }  
  69.     get department() { return this.employeeForm.get('department'); }  
  70.     get city() { return this.employeeForm.get('city'); }  
  71. }  

This component will be used for both adding and editing the employee data. Since we are using a form model along with clientside validation to Add and Edit customer data we have imported classes from @angular/forms. The code to create the form has been put inside the constructor so that the form will be displayed as the page loads.

This component will handle both Add and Edit request. So how will the system will differentiate between both requests? The answer is routing. We need to define two different route parameters, one for Add employee record and another to edit employee record. We will be defining these in app.module.shared.ts file shortly.

We have declared variable title to show on the top of page and variable id to store the employee id passed as the parameter in case of edit request. To read the employee id from the URL we will use ActivatedRoute.snapshot inside the constructor and set the value of variable id.

Inside ngOnInit we will check if the id is set then we will change the title to “Edit”, get the data for that id from our service and populate the fields in our form. The value read from database will be returned as JSON and have all the properties same as we declared in our FormBuilder, hence we use setValue method to populate our form.

The save method will be called on clicking on “Save” button of our form. Based on whether it is an Add operation or an Edit operation it will call the corresponding method from our service and then upon success redirect back to fetch-employee page.

In the last we have also defined getter functions for the control names of our form to enable clientside validation.

Open Addemployee.component.html file and put the following code into it,
  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <meta charset="utf-8" />  
  5.     <title></title>  
  6. </head>  
  7. <body>  
  8.   
  9.     <h1>{{title}}</h1>  
  10.     <h3>Employee</h3>  
  11.     <hr />  
  12.     <form [formGroup]="employeeForm" (ngSubmit)="save()" #formDir="ngForm" novalidate>  
  13.   
  14.         <div class="form-group row">  
  15.             <label class=" control-label col-md-12" for="Name">Name</label>  
  16.             <div class="col-md-4">  
  17.                 <input class="form-control" type="text" formControlName="name">  
  18.             </div>  
  19.             <span class="text-danger" *ngIf="employeeForm.hasError('required', 'name') && formDir.submitted">  
  20.                 Name is required.  
  21.             </span>  
  22.         </div>  
  23.         <div class="form-group row">  
  24.             <label class="control-label col-md-12" for="Gender">Gender</label>  
  25.             <div class="col-md-4">  
  26.                 <select class="form-control" data-val="true" formControlName="gender">  
  27.                     <option value="">-- Select Gender --</option>  
  28.                     <option value="Male">Male</option>  
  29.                     <option value="Female">Female</option>  
  30.                 </select>  
  31.             </div>  
  32.             <span class="text-danger" *ngIf="employeeForm.hasError('required', 'gender') && formDir.submitted">  
  33.                 Gender is required  
  34.             </span>  
  35.         </div>  
  36.         <div class="form-group row">  
  37.             <label class="control-label col-md-12" for="Department">Department</label>  
  38.             <div class="col-md-4">  
  39.                 <input class="form-control" type="text" formControlName="department">  
  40.             </div>  
  41.             <span class="text-danger" *ngIf="employeeForm.hasError('required', 'department') && formDir.submitted">  
  42.                 Department is required  
  43.             </span>  
  44.         </div>  
  45.         <div class="form-group row">  
  46.             <label class="control-label col-md-12" for="City">City</label>  
  47.             <div class="col-md-4">  
  48.                 <input class="form-control" type="text" formControlName="city" data-val="true">  
  49.             </div>  
  50.             <span class="text-danger" *ngIf="employeeForm.hasError('required', 'city') && formDir.submitted">  
  51.                 City is required  
  52.             </span>  
  53.         </div>  
  54.         <div class="form-group">  
  55.             <button type="submit" class="btn btn-default">Save</button>  
  56.             <button class="btn" (click)="cancel()">Cancel</button>  
  57.         </div>  
  58.     </form>  
  59. </body>  
  60. </html>  

Here you can observe that we have attribute [formGroup]="employeeForm”, which is our defined form group name in Addemployee.component.ts file. “(ngSubmit)="save()" will invoke our save method on form submit.

Also, every input control has attribute formControlName="xyz", this is used to bind FormControl to HTML. We have also defined error message for client-side validation check and it will be invoked on form submission only.

Defining route and navigation menu for our Application

Open /app/app.module.shared.ts file and put the following code into it.
  1. import { NgModule } from '@angular/core';  
  2. import { EmployeeService } from './services/empservice.service'  
  3. import { CommonModule } from '@angular/common';  
  4. import { FormsModule, ReactiveFormsModule } from '@angular/forms';  
  5. import { HttpModule } from '@angular/http';  
  6. import { RouterModule } from '@angular/router';  
  7.   
  8. import { AppComponent } from './components/app/app.component';  
  9. import { NavMenuComponent } from './components/navmenu/navmenu.component';  
  10. import { HomeComponent } from './components/home/home.component';  
  11. import { FetchEmployeeComponent } from './components/fetchemployee/fetchemployee.component'  
  12. import { createemployee } from './components/addemployee/AddEmployee.component'  
  13.   
  14. @NgModule({  
  15.     declarations: [  
  16.         AppComponent,  
  17.         NavMenuComponent,  
  18.         HomeComponent,  
  19.         FetchEmployeeComponent,  
  20.         createemployee,  
  21.     ],  
  22.     imports: [  
  23.         CommonModule,  
  24.         HttpModule,  
  25.         FormsModule,  
  26.         ReactiveFormsModule,  
  27.         RouterModule.forRoot([  
  28.             { path: '', redirectTo: 'home', pathMatch: 'full' },  
  29.             { path: 'home', component: HomeComponent },  
  30.             { path: 'fetch-employee', component: FetchEmployeeComponent },  
  31.             { path: 'register-employee', component: createemployee },  
  32.             { path: 'employee/edit/:id', component: createemployee },  
  33.             { path: '**', redirectTo: 'home' }  
  34.         ])  
  35.     ],  
  36.     providers: [EmployeeService]  
  37. })  
  38. export class AppModuleShared {  
  39. }  

Here we have also imported all our components and defined route for our application as below,

  • home which will redirect to home component
  • fetch-employee to display all employee data using fetchemployee compoenent
  • register-employee to add new employee record using addemployee component
  • employee/edit/:id to edit existing employee record using addemployee component
  • For any other path it will be redirected to home component
One last thing is to define navigation menu for our application. Open /app/components/navmenu/navmenu.component.html file and put the following code to it.
  1. <div class='main-nav'>  
  2.     <div class='navbar navbar-inverse'>  
  3.         <div class='navbar-header'>  
  4.             <button type='button' class='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse'>  
  5.                 <span class='sr-only'>Toggle navigation</span>  
  6.                 <span class='icon-bar'></span>  
  7.                 <span class='icon-bar'></span>  
  8.                 <span class='icon-bar'></span>  
  9.             </button>  
  10.             <a class='navbar-brand' [routerLink]="['/home']">ASPCoreWithAngular</a>  
  11.         </div>  
  12.         <div class='clearfix'></div>  
  13.         <div class='navbar-collapse collapse'>  
  14.             <ul class='nav navbar-nav'>  
  15.                 <li [routerLinkActive]="['link-active']">  
  16.                     <a [routerLink]="['/home']">  
  17.                         <span class='glyphicon glyphicon-home'></span> Home  
  18.                     </a>  
  19.                 </li>  
  20.                 <li [routerLinkActive]="['link-active']">  
  21.                     <a [routerLink]="['/fetch-employee']">  
  22.                         <span class='glyphicon glyphicon-th-list'></span> Fetch employee  
  23.                     </a>  
  24.                 </li>  
  25.             </ul>  
  26.         </div>  
  27.     </div>  
  28. </div>  

And that’s it. We have created our first ASP.NET Core application using Angular 5. Press F5 to launch the application.

A web page will open as shown in the image below. Notice the URL showing route for our home component. And navigation menu on the left showing navigation link for Home and Fetch Employee pages.



Click on Fetch Employee in the navigation menu. It will redirect to fetch employee component and displays all the employee data on the page.

Since we have not added any data hence it is empty.

Click on CreateNew to navigate to /register-employee page. Add a new Employee record as shown in the image below



If we miss the data in any field while creating employee record, we will get a required field validation error message.



After inserting the data in all the fields, click on "Save" button. The new employee record will be created and you will be redirected to the /fetch-employee page, displaying records of all the employees. Here, we can also see action methods Edit and Delete.



If we want to edit an existing employee record, then click Edit action link. It will open Edit page as below where we can change the employee data. Notice that we have passed employee id in the URL parameter.



Here we have changed the Department of employee Swati from Marketing to HR. Click on "Save" to return to the fetch-employee page to see the updated changes as highlighted in the image below.



If we miss any fields while editing employee records, then Edit view will also throw required field validation error message as shown in the image below.



Now, we will perform Delete operation on an employee named Dhiraj having Employee ID 2. Click on Delete action link which will open a javascript confirmation box asking for a confirmation to delete.



Once we click on Delete button the employee with name Dhiraj will be deleted and we can see the updated list of employees as shown below.



Conclusion

We have created an ASP.NET Core application using Angular 5 on the frontend, Web API and ADO.NET in the backend with the help of VS 2017. If you are a fan of Razor and do not want to use Angular frontend, then you can also create this same application using Razor.

To know more, please refer to my previous article CRUD Operation With ASP.NET Core MVC Web App Using ADO.NET