Before proceeding further, please read the following previous articles for updating .NET Core version to use Angular.
Getting Started
- Start Visual Studio 2017.
- Select "New Project".
- Select .NET Core from Web template and select ASP.NET Core Web Application.
- Provide a project name.
- Provide project location to save and click OK.

Image 1. - Select Angular from the given templates.
- Select .NET Core version and click OK.

Image 2. - Here is the structure of your project.

Image 3.
Here is my database table schema structure diagram.
Image 4.
Now, let’s work on functionality part. First of all, add a connection string in appsettings.json.
Now, go to Tools >> NuGet Package Manager >> Package Manager Console now.
Image 5.
Add Scaffold DB Context command and provide the database connection string, output directory name, and table’s name.

Wait until the command executes. Once done, check in the Models folder.
Image 7.
As you can see 3 class are added which has all model classes and context in the Models folder.
First thing before going further, go in the dbcotext class and comment this line of code which has hardcoded connection string.
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- //if (!optionsBuilder.IsConfigured)
- //{
- //#warning To protect potentially sensitive information in your connection string, you should move it out of source code. See http://go.microsoft.com/fwlink/?LinkId=723263 for guidance on storing connection strings.
- //optionsBuilder.UseSqlServer(@"Server=localhost;Database=NORTHWND;Trusted_Connection=True;");
- // }
- }
Now, go to the Startup.cs class and add the following line for connection string and to serialize JSON data.
- public void ConfigureServices(IServiceCollection services) {
- // Add framework services.
- services.AddDbContext < NORTHWNDContext > (options => options.UseSqlServer(Configuration.GetConnectionString("NORTHWNDConnString")));
- services.AddScoped < EmployeeDAL > ();
- services.AddMvc().AddJsonOptions(x => x.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore);
- }
EmployeeDAL.cs
- using Microsoft.EntityFrameworkCore;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- namespace secondsample.Models {
- public class EmployeeDAL {
- private readonly NORTHWNDContext _context;
- public EmployeeDAL(NORTHWNDContext context) {
- _context = context;
- }
- /// <summary>
- /// gets all employees list
- /// </summary>
- /// <returns></returns>
- public async Task < IEnumerable < Employees >> GetAllEmployees() {
- try {
- return await _context.Employees.ToListAsync();
- } catch {
- throw;
- }
- }
- /// <summary>
- /// add new employee
- /// </summary>
- /// <param name="employee"></param>
- /// <returns></returns>
- public int AddEmployee(Employees employee) {
- try {
- _context.Employees.Add(employee);
- _context.SaveChanges();
- return 1;
- } catch {
- throw;
- }
- }
- /// <summary>
- /// update an existing employee
- /// </summary>
- /// <param name="employee"></param>
- /// <returns></returns>
- public int UpdateEmployee(Employees employee) {
- try {
- _context.Entry(employee).State = EntityState.Modified;
- _context.SaveChanges();
- return 1;
- } catch {
- throw;
- }
- }
- /// <summary>
- /// get an employee detail
- /// </summary>
- /// <param name="EmployeeID"></param>
- /// <returns></returns>
- public Employees GetEmployee(int EmployeeID) {
- try {
- Employees employee = _context.Employees.Find(EmployeeID);
- return employee;
- } catch {
- throw;
- }
- }
- /// <summary>
- /// Delete an employee
- /// </summary>
- /// <param name="EmployeeID"></param>
- /// <returns></returns>
- public int DeleteEmployee(int EmployeeID) {
- try {
- Employees employee = _context.Employees.Find(EmployeeID);
- _context.Employees.Remove(employee);
- _context.SaveChanges();
- return 1;
- } catch {
- throw;
- }
- }
- }
- }
EmployeeController.cs
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using Microsoft.AspNetCore.Mvc;
- using secondsample.Models;
- namespace secondsample.Controllers {
- [Route("api/Employees")]
- public class EmployeeController: Controller {
- private readonly EmployeeDAL _employeeDAL;
- public EmployeeController(EmployeeDAL employeeDAL) {
- _employeeDAL = employeeDAL;
- }
- [HttpGet]
- [Route("GetEmployees")]
- public async Task < IEnumerable < Employees >> GetEmployees() {
- return await _employeeDAL.GetAllEmployees();
- }
- [HttpPost]
- [Route("AddEmployee")]
- public int AddEmployee([FromBody] Employees employee) {
- return _employeeDAL.AddEmployee(employee);
- }
- [HttpGet]
- [Route("GetEmployeeDetail/{employeeID}")]
- public Employees GetEmployeeDetail(int employeeID) {
- return _employeeDAL.GetEmployee(employeeID);
- }
- [HttpPut]
- [Route("EditEmployee")]
- public int EditEmployee([FromBody] Employees employee) {
- return _employeeDAL.UpdateEmployee(employee);
- }
- [HttpDelete]
- [Route("DeleteEmployee/{EmployeeID}")]
- public int DeleteEmployee(int EmployeeID) {
- return _employeeDAL.DeleteEmployee(EmployeeID);
- }
- }
- }
Add a new services folder in app folder which is in ClientApp directory, add a new TypeScript file, and add the following code.
employeeservices.ts
- import {
- Injectable,
- Inject
- } from '@angular/core';
- import {
- Http,
- Response
- } from '@angular/http';
- import {
- Observable
- } from 'rxjs/Observable';
- import {
- Router
- } from '@angular/router';
- import 'rxjs/add/operator/map';
- import 'rxjs/add/operator/catch';
- import 'rxjs/add/observable/throw';
- @Injectable()
- export class EmployeeService {
- myAppUrl: string = "";
- constructor(private _http: Http, @Inject('BASE_URL') baseUrl: string) {
- this.myAppUrl = baseUrl;
- }
- getEmployees() {
- return this._http.get(this.myAppUrl + 'api/Employees/GetEmployees').map((response: Response) => response.json()).catch(this.errorHandler);
- }
- getEmployeeById(EmployeeID: number) {
- return this._http.get(this.myAppUrl + "api/Employees/GetEmployeeDetail/" + EmployeeID).map((response: Response) => response.json()).catch(this.errorHandler)
- }
- deleteEmployee(EmployeeID: number) {
- return this._http.delete(this.myAppUrl + "api/Employees/DeleteEmployee/" + EmployeeID).map((response: Response) => response.json()).catch(this.errorHandler);
- }
- updateEmployee(employee: any) {
- return this._http.put(this.myAppUrl + 'api/Employees/EditEmployee', employee).map((response: Response) => response.json()).catch(this.errorHandler);
- }
- saveEmployee(employee: any) {
- return this._http.post(this.myAppUrl + 'api/Employees/AddEmployee', employee).map((response: Response) => response.json()).catch(this.errorHandler)
- }
- errorHandler(error: Response) {
- console.log(error);
- return Observable.throw(error.json().error || 'Server error');
- }
- }
employeedata.components.ts
- import {
- Component,
- Inject
- } from '@angular/core';
- import {
- Http,
- Headers
- } from '@angular/http';
- import {
- EmployeeService
- } from '../../services/employeeservice'
- import {
- Router,
- ActivatedRoute
- } from '@angular/router';
- @Component({
- selector: 'employeedata',
- templateUrl: './employeedata.component.html'
- })
- export class EmployeeDataComponent {
- public employeelist: EmployeeList[];
- constructor(public http: Http, private _router: Router, private _employeeService: EmployeeService) {
- this.getEmployees();
- }
- getEmployees() {
- this._employeeService.getEmployees().subscribe(data => this.employeelist = data)
- console.log(this.employeelist);
- }
- deleteEmployee(employeeId: number) {
- var ans = confirm("Do you want to delete employee with Id: " + employeeId);
- if (ans) {
- this._employeeService.deleteEmployee(employeeId).subscribe((data) => {
- this.getEmployees();
- }, error => console.error(error))
- }
- }
- }
- interface EmployeeList {
- EmployeeID: number;
- LastName: string;
- FirstName: string;
- Title: string;
- Address: string;
- City: string;
- Region: string;
- PostalCode: string;
- Country: string;
- Notes: string;
- }
- <h1>Employee Data</h1>
- <p>This component demonstrates fetching Employee data from the server.</p>
- <p *ngIf="!employeelist"><em>Loading...</em></p>
- <p> <a [routerLink]="['/add-employee']">Create New</a> </p>
- <table class='table table-bordered' *ngIf="employeelist">
- <thead style="background-color:green;font-weight:bold;color:white;">
- <tr>
- <th>EmployeeID</th>
- <th>Name</th>
- <th>Title</th>
- <th>City</th>
- <th>Region</th>
- <th>Zip</th>
- <th>Country</th>
- <th>Notes</th>
- <th>Actions</th>
- </tr>
- </thead>
- <tbody>
- <tr *ngFor="let emp of employeelist">
- <td>{{ emp.employeeId }}</td>
- <td>{{ emp.lastName }}, {{ emp.firstName }}</td>
- <td>{{ emp.title }}</td>
- <td>{{ emp.city }}</td>
- <td>{{ emp.region }}</td>
- <td>{{ emp.postalCode }}</td>
- <td>{{ emp.country }}</td>
- <td>{{ emp.notes }}</td>
- <td> <a [routerLink]="['/employee/edit/', emp.employeeId]">Edit</a> | <a [routerLink]="" (click)="deleteEmployee(emp.employeeId)">Delete</a> </td>
- </tr>
- </tbody>
- </table>
- import {
- Component,
- OnInit
- } from '@angular/core';
- import {
- Http,
- Headers
- } from '@angular/http';
- import {
- NgForm,
- FormBuilder,
- FormGroup,
- Validators,
- FormControl
- } from '@angular/forms';
- import {
- Router,
- ActivatedRoute
- } from '@angular/router';
- import {
- EmployeeDataComponent
- } from '../employeedata/employeedata.component';
- import {
- EmployeeService
- } from '../../services/employeeservice';
- @Component({
- templateUrl: './addemployee.component.html'
- })
- export class AddEmployee implements OnInit {
- employeeForm: FormGroup;
- title: string = "Create";
- employeeId: number;
- errorMessage: any;
- constructor(private _fb: FormBuilder, private _avRoute: ActivatedRoute, private _employeeService: EmployeeService, private _router: Router) {
- if (this._avRoute.snapshot.params["employeeID"]) {
- this.employeeId = this._avRoute.snapshot.params["employeeID"];
- //alert(this.employeeId);
- }
- this.employeeForm = this._fb.group({
- employeeId: 0,
- firstName: ['', [Validators.required]],
- lastName: ['', [Validators.required]],
- title: ['', [Validators.required]],
- city: ['', [Validators.required]],
- region: ['', [Validators.required]],
- postalCode: ['', [Validators.required]],
- country: ['', [Validators.required]],
- notes: ['', [Validators.required]],
- titleOfCourtesy: ['', []],
- birthDate: ['', []],
- hireDate: ['', []],
- address: ['', []],
- homePhone: ['', []],
- extension: ['', []],
- photo: ['', []],
- reportsTo: ['', []],
- photoPath: ['', []],
- salary: ['', []],
- reportsToNavigation: ['', []],
- employeeTerritories: ['', []],
- inverseReportsToNavigation: ['', []]
- })
- }
- ngOnInit() {
- if (this.employeeId > 0) {
- this.title = "Edit";
- this._employeeService.getEmployeeById(this.employeeId).subscribe(resp => this.employeeForm.setValue(resp), error => this.errorMessage = error);
- }
- }
- save() {
- if (!this.employeeForm.valid) {
- return;
- }
- if (this.title == "Create") {
- this._employeeService.saveEmployee(this.employeeForm.value).subscribe((data) => {
- this._router.navigate(['/employee-data']);
- }, error => this.errorMessage = error)
- } else if (this.title == "Edit") {
- this._employeeService.updateEmployee(this.employeeForm.value).subscribe((data) => {
- this._router.navigate(['/employee-data']);
- }, error => this.errorMessage = error)
- }
- }
- cancel() {
- this._router.navigate(['/employee-data']);
- }
- get firstName() {
- return this.employeeForm.get('firstName');
- }
- get lastName() {
- return this.employeeForm.get('lastName');
- }
- get title1() {
- return this.employeeForm.get('title');
- }
- get city() {
- return this.employeeForm.get('city');
- }
- get region() {
- return this.employeeForm.get('region');
- }
- get postalCode() {
- return this.employeeForm.get('postalCode');
- }
- get country() {
- return this.employeeForm.get('country');
- }
- get notes() {
- return this.employeeForm.get('notes');
- }
- get titleOfCourtesy() {
- return this.employeeForm.get('titleOfCourtesy');
- }
- get birthDate() {
- return this.employeeForm.get('birthDate');
- }
- get hireDate() {
- return this.employeeForm.get('hireDate');
- }
- get address() {
- return this.employeeForm.get('address');
- }
- get homePhone() {
- return this.employeeForm.get('homePhone');
- }
- get extension() {
- return this.employeeForm.get('extension');
- }
- get photo() {
- return this.employeeForm.get('photo');
- }
- get reportsTo() {
- return this.employeeForm.get('reportsTo');
- }
- get photoPath() {
- return this.employeeForm.get('photoPath');
- }
- get salary() {
- return this.employeeForm.get('salary');
- }
- get reportsToNavigation() {
- return this.employeeForm.get('reportsToNavigation');
- }
- get employeeTerritories() {
- return this.employeeForm.get('employeeTerritories');
- }
- get inverseReportsToNavigation() {
- return this.employeeForm.get('inverseReportsToNavigation');
- }
- }
- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8" />
- <title></title>
- </head>
- <body>
- <h1>{{title}}</h1>
- <h3>Employee</h3>
- <hr />
- <form [formGroup]="employeeForm" (ngSubmit)="save()" #formDir="ngForm" novalidate>
- <div class="form-group row"> <label class=" control-label col-md-12" for="FirstName">First Name</label>
- <div class="col-md-4"> <input class="form-control" type="text" formControlName="firstName"> </div> <span class="text-danger" *ngIf="employeeForm.hasError('required', 'firstName') && formDir.submitted">
- First Name is required.
- </span> </div>
- <div class="form-group row"> <label class=" control-label col-md-12" for="LastName">Last Name</label>
- <div class="col-md-4"> <input class="form-control" type="text" formControlName="lastName"> </div> <span class="text-danger" *ngIf="employeeForm.hasError('required', 'lastName') && formDir.submitted">
- Last Name is required.
- </span> </div>
- <div class="form-group row"> <label class="control-label col-md-12" for="Title">Title</label>
- <div class="col-md-4"> <input class="form-control" type="text" formControlName="title"> </div> <span class="text-danger" *ngIf="employeeForm.hasError('required', 'title') && formDir.submitted">
- Title is required
- </span> </div>
- <div class="form-group row"> <label class="control-label col-md-12" for="City">City</label>
- <div class="col-md-4"> <input class="form-control" type="text" formControlName="city"> </div> <span class="text-danger" *ngIf="employeeForm.hasError('required', 'city') && formDir.submitted">
- City is required
- </span> </div>
- <div class="form-group row"> <label class="control-label col-md-12" for="Region">Region</label>
- <div class="col-md-4"> <input class="form-control" type="text" formControlName="region"> </div> <span class="text-danger" *ngIf="employeeForm.hasError('required', 'region') && formDir.submitted">
- Region is required
- </span> </div>
- <div class="form-group row"> <label class="control-label col-md-12" for="postalCode">Zip</label>
- <div class="col-md-4"> <input class="form-control" type="text" formControlName="postalCode"> </div> <span class="text-danger" *ngIf="employeeForm.hasError('required', 'postalCode') && formDir.submitted">
- Zip is required
- </span> </div>
- <div class="form-group row"> <label class="control-label col-md-12" for="Country">Country</label>
- <div class="col-md-4"> <input class="form-control" type="text" formControlName="country"> </div> <span class="text-danger" *ngIf="employeeForm.hasError('required', 'country') && formDir.submitted">
- Country is required
- </span> </div>
- <div class="form-group row"> <label class="control-label col-md-12" for="Notes">Notes</label>
- <div class="col-md-4"> <textarea class="form-control" type="text" formControlName="notes"></textarea> </div> <span class="text-danger" *ngIf="employeeForm.hasError('required', 'notes') && formDir.submitted">
- Notes is required
- </span> </div>
- <div class="form-group"> <button type="submit" class="btn btn-default">Save</button> <button class="btn" (click)="cancel()">Cancel</button> </div>
- </form>
- </body>
- </html>
- import {
- NgModule
- } from '@angular/core';
- import {
- EmployeeService
- } from './services/employeeservice'
- import {
- CommonModule
- } from '@angular/common';
- import {
- FormsModule,
- ReactiveFormsModule
- } from '@angular/forms';
- import {
- HttpModule
- } from '@angular/http';
- import {
- RouterModule
- } from '@angular/router';
- import {
- AppComponent
- } from './components/app/app.component';
- import {
- NavMenuComponent
- } from './components/navmenu/navmenu.component';
- import {
- HomeComponent
- } from './components/home/home.component';
- import {
- FetchDataComponent
- } from './components/fetchdata/fetchdata.component';
- import {
- CounterComponent
- } from './components/counter/counter.component';
- import {
- EmployeeDataComponent
- } from './components/employeedata/employeedata.component';
- import {
- AddEmployee
- } from './components/addemployee/addemployee.component';
- @NgModule({
- declarations: [
- AppComponent,
- NavMenuComponent,
- CounterComponent,
- FetchDataComponent,
- EmployeeDataComponent,
- HomeComponent,
- AddEmployee
- ],
- imports: [
- CommonModule,
- HttpModule,
- FormsModule,
- ReactiveFormsModule,
- RouterModule.forRoot([{
- path: '',
- redirectTo: 'home',
- pathMatch: 'full'
- }, {
- path: 'home',
- component: HomeComponent
- }, {
- path: 'counter',
- component: CounterComponent
- }, {
- path: 'fetch-data',
- component: FetchDataComponent
- }, {
- path: 'employee-data',
- component: EmployeeDataComponent
- }, {
- path: 'add-employee',
- component: AddEmployee
- }, {
- path: 'employee/edit/:employeeID',
- component: AddEmployee
- }, {
- path: '**',
- redirectTo: 'home'
- }])
- ],
- providers: [EmployeeService]
- })
- export class AppModuleShared {}
- <div class='main-nav'>
- <div class='navbar navbar-inverse'>
- <div class='navbar-header'> <button type='button' class='navbar-toggle' data-toggle='collapse' data-target='.navbar-collapse'>
- <span class='sr-only'>Toggle navigation</span>
- <span class='icon-bar'></span>
- <span class='icon-bar'></span>
- <span class='icon-bar'></span>
- </button> <a class='navbar-brand' [routerLink]="['/home']">CRUD Operations in .NET Core with Angular Sample by Raj</a> </div>
- <div class='clearfix'></div>
- <div class='navbar-collapse collapse'>
- <ul class='nav navbar-nav'>
- <li [routerLinkActive]="['link-active']"> <a [routerLink]="['/home']">
- <span class='glyphicon glyphicon-home'></span> Home
- </a> </li>
- <li [routerLinkActive]="['link-active']"> <a [routerLink]="['/employee-data']">
- <span class='glyphicon glyphicon-th-list'></span> Employees
- </a> </li>
- </ul>
- </div>
- </div>
- </div>
Image 8.As you can see when click on Employees tab then data is loading in the grid, that means, our data is coming correct and functionality is working. Now, let’s click on Edit link to edit existing record.
Image 9.
You can edit whatever information you like to edit and click on save button. Now, let’s create a new record.
Image 10.
You can delete any existing record on click on Delete link.
I don’t want to make this article bigger, so I am wrapping up here. I will upload source code soon and will share the link.
Conclusion
In this article, we learned how to build CRUD functionality with .NET Core angular and Entity Framework with SQL Server database.

Pravin LalgePosted Sep 19, 2018, 4:16 AM
Hello Raj...nice article..
Vivek KrPosted Sep 14, 2018, 4:37 AM
It Helps to start with asp.net and angular
Arvind SinghPosted Apr 5, 2018, 11:26 PM
Very nice article, one thing want to point out here, most of screen shots and codes here, try to write some explanation also.
athman abedPosted Apr 5, 2018, 7:40 PM
Hi, I tried this but got:dotnet ef migrations add initial-migration https://showbox.onl/ https://vidmate.onl/ https://mobdro.onl/ Unable to create an object of type ‘MyContext’. Add an implementation of ‘IDesignTimeDbContextFactory’ to the project, or see https://go.microsoft.com/fwlink/?linkid=851728 for additional patterns supported at design time.
AyoubPosted Apr 3, 2018, 11:57 AM
Nice article, thanks for sharing.
Tarun RajakPosted Apr 1, 2018, 11:51 PM
Hi Raj, Thanx for sharing this article. Which version of Angular you used here?