Introduction
This is the first part of this series. In this series, we will create a SPA Application, using Angular 2, ASP.NET Core 1.1 and Entity Framework Core. Here, we use Angular 2 as UI for the Application, using ASP.NET Core MVC. We will perform Server side tasks and using Entity Framework Core, we will perform all the database level operations. In this series, we create an Employee Management system project. In this management system, we provide features to see the list of all employees, edit the existing employee, delete any particular employee and enter a new employee. Let’s go through the agenda of this series.
Agenda
- Setup development environment for Angular 2.
- Understand the structure of an Application.
- Add Entity Framework in project.
- Create new pages to see the Employee List and also for Insert, Update and Delete operations.
- Perform Angular 2 routing.
- Add Services.
Prerequisites
There some minimum configuration, which must be configured in your system before staring the work on this series.
- Visual Studio 2015 Update 3 or Visual Studio 2017.
- .NET Core 1.0.
- Type Script 2.0.
- js Version 6 or later.
After meeting all the above requirements, now we can setup SPA Application in some simple steps.
Getting started
The easiest way to get started is by using one of the project templates, which are made available. These plug into the standard dotnet new command and work on Windows, Mac in addition to Linux. To install the (Single Page Application)SPA templates, open the command prompt and run the command given below.
dotnet new --install Microsoft.AspNetCore.SpaTemplates::*
The command given above takes some time and installs several templates for SPA like Angular, Knockout.js, React etc. The benefit of all these templates are that we don’t need to worry about the whole setup process.
To generate a new project, create an empty folder and name this project as EMS here. EMS is an abbreviation for Employee Management System. After creating an empty folder, now change the directory and go to this project. Now, run the command dotnet new angular.
This command creates a template project for Angular 2 Application. Now, run “dotnet restore” commanpm nd. This command builds MSBuild file and restore all .NET dependencies.
After installing all the .NET dependencies, now we install Node.js dependencies. Run “npm install” command. This command takes couples of minutes to install the required Node.js dependencies.
After creating the template project and installing all the required dependencies, now run “start EMS.csproj” command. This command will open your project in Visual Studio. Here, I am using Visual Studio 2017.
Now, press Ctrl + F5 and run the project.
After running the project, if you get the above screen, then Congrats, as you successfully created Angular 2 Application. If you make any changes either in “.ts” files or “.html” file, you will get the live update as soon as you save the changes and don’t need to refresh the Browser.
Structure of the Application
After creating and running the Application successfully, let’s understand the structure of the project. Now, open Solution Explorer Window and you will find the project structure given below.
Following are the major parts of our Application.
Dependencies
This section contains three types of the dependencies and npm dependencies are related to our Client Application. NuGet contains .NET Core level dependencies. SDK section contains system level dependencies.
launchSettings.json
This JSON file holds the project specific settings, which are associated with each debug profile, Visual Studio is configured to launch the Application, including any environment variables, which should be used. This file defines ApplicationURL, SSL port number and mode of authentication.
wwwroot
wwwroot section contains the “dist” folder. Here, dist folder contains the compiled code of our ClinetApp. All the code, which we write in template(.ts) or .html pages converts into a compiled code and save in a main-client.js file. This file contains the compiled form of all the components, Service and all other resources, which we create in our ClientApp folder.
If you go to Index.cshtml view of Home controller, you fill find that we referenced the main-client.js file in Application startup process.
- @{
- ViewData["Title"] = "Home Page";
- }
-
- <app asp-prerender-module="ClientApp/dist/main-server">Loading...</app>
-
- <script src="~/dist/vendor.js" asp-append-version="true"></script>
- @section scripts {
- <script src="~/dist/main-client.js" asp-append-version="true"></script>
- }
ClientApp
This is client section of our project. Here, we write all Angular2 related code. Create component and Services. App folder contains components and app.module.ts file. The boot-client.ts file defines the root component selector.
Controllers
In this section, we create MVC Controllers. In this project, we will use controller to get the data from the database.
Views
It defines V part of the MVC project, I think, we are already aware of Views.
Appsettings.json
Instead of web.config, all your settings are now located in appsettings.json. It contains all the configuration information in form of key-value pair. In this file, we define connection string and other Application level settings.
Packages.json
This file contains all Angular2 related dependencies.
Program.cs
This is the entry point of the Application and is used to host the Application. In this file, we simply do the job of configuring & launching a host, using WebHostBuilder
Startup.cs
Startup.cs file works like a middleware and provide all the Services, which system requires to run.
tsconfig.cs
This file contains TypeScript configuration settings.
Webpack.config.js
Webpack works like a Package Manger and module bundler. It takes all the project modules with dependencies and generates the static assets, which represents these modules. Webpack and build and bundle CSS, JavaScript file, images all other static contents.
Configure Entity Framework
Now, we use Code First approach and create the database and tables. In our Application, we will use SQL Server for the database, so we need to install Entity Framework for SQL Server. To configure Entity Framework for SQL Server, we need to add SQL Server database provider.
Open Package Manager Console and run the command given below.
“Install-Package Microsoft.EntityFrameworkCore.SqlServer”
We will be using some Entity Framework tools to maintain the database. Thus, we need to install the tools packages as well. Hence, run the command given below to add all the required tools.
“Install-Package Microsoft.EntityFrameworkCore.Tools”
Create Entity classes
After adding the dependencies for Entity Framework, let’s create Employee and Project entity class. There will be a many to one relationship between Employee and Project entity. This means one employee can have only one project at a time but there can be more than one employees in a single project. Create a Model folder and add an Employee class in this folder.
Employee Entity
Add an Employee class in Models folder and replace the code of Employee class with the code given below.
- using System.ComponentModel.DataAnnotations;
- using System.ComponentModel.DataAnnotations.Schema;
-
- namespace EMS.Models
- {
- public class Employee
- {
- [Key]
- [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
- public int EmployeeId { get; set; }
- public string EmployeeName { get; set; }
- public string Designation { get; set; }
- public string Skills { get; set; }
- public int ProjectId { get; set; }
- public Project Project { get; set; }
- }
- }
In the code given above, EmployeeId property is a primary key for an Employee entity and it is also an identity type. The ProjectId is foreign key and corresponding navigation property is Project.
Project Entity
Now, add another class in Model folder and name this class Project, and replace the code of this class with the code given below.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
-
- namespace EMS.Model
- {
- public class Project
- {
- public int ProjectId { get; set; }
- public string ProjectName { get; set; }
- public DateTime StartDate { get; set; }
- public DateTime EndDate { get; set; }
- }
- }
The ProjectId property is a primary key for this entity and other properties defines the information about the project.
Add DbContext Class:
The main class of any Entity Framework structure is DbCntext class. In this class, we define all the entities, which are used to create the table in the database. Now, add another class in Model folder and name it as EmployeeContext. This class will be derived from System.Data.Entity.DbContext class. Replace the code of this class with the code given below.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using Microsoft.EntityFrameworkCore;
- using EMS.Models;
-
- namespace EMS.Model
- {
- public class EmployeeContext:DbContext
- {
- public EmployeeContext(DbContextOptions<EmployeeContext> options):base(options)
- {
-
- }
- public DbSet<Employee> Employee { get; set; }
- public DbSet<Project> Project { get; set; }
- }
- }
In the code given above, we defined two Dbset properties for Employee and Project class. This property will create two tables in the database and name will be same, as defined in Dbset property.
Register Context with dependency Injection
After creating all entitities and dbContext classes, now we add a Service for Entity Framework such that any component requires this Service, which can be provided by constructor. In our controller constructor, we use this Service to get the context instance. Now, open startup.cs and add the code given below to ConfigureServices method.
services.AddDbContext<EmployeeContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
In the code given above, we register a Service for DbContext. Here, DefaultConnection provides the connection string, which is defined in our appsettings.json. Now, open your appsettings.json” file and add the code given below. Replace the Server name with your SQL Server name.
- {
- "ConnectionStrings": {
- "DefaultConnection": "Server=*******;Database=Employee;Trusted_Connection=True;MultipleActiveResultSets=true"
- },
- "Logging": {
- "IncludeScopes": false,
- "LogLevel": {
- "Default": "Debug",
- "System": "Information",
- "Microsoft": "Information"
- }
- }
- }
Add Migration and create a database
After configuring dbContext and entity classes now we add the migration and using the “Update-Database” command we will create our project database. First, we add the migration to open your “Package Manager Console”. Run “Add-Migration firstMigration” command. This command will add the Migrations folder in your project and first file in Migrations folder contains all the information on how to create your database.
Now, we will run Update-Database command. This command takes codes, which are available in migration class and updates your database. In our case this command create an “Employee” database in SQL Server, which contains all the table and properties, which we defined earlier in our model classes.
Now, open your SQL Server and you will find that Employee database has been added.
Add initial data
Now, our tables and database are ready. Let’s add some initial data into our tables.
Add data into Project Table
- INSERT INTO dbo.Project
- (
- ProjectName,
- StartDate,
- EndDate
- )
- VALUES( N'Lions',CAST('02/01/2017' as datetime),CAST('04/05/2017' AS datetime) ),( N'OUP',CAST('08/09/2016' AS datetime),CAST('12/03/2017' AS datetime) ),
- ( N'VMesh',CAST('12/04/2016' as date),CAST('04/01/2017' as date) )
AdddData into an Employee Table
- insert into Employee
- (Designation,EmployeeName,ProjectId,Skills)
- values('Developer','Raj Kumar',2,'C#,Asp.Net,MVC'),
- ('Mobile Developer','Ankur Verma',3,'Java, Android Studio, Xamarin'),
- ('Developer','Dheeraj Sharma',1,'C#,Asp.Net,MVC,AngularJS'),
- ('Developer','Dhramveer',2,'C#,Asp.Net,MVC,AngularJS,Node.js'),
- ('Mobile Developer','Shivam Kumar',1,'Java, Android Studio, Xamarin')
Now, our database and an Application setup is ready. Let’s start work with View section of an Application.
Show Employee List
Now, go to “app.modules.ts” file in “App” folder. In this file, you find that some default routes are defined like counter, home and fetch-data. We don’t need all these routes, so remove counter and fetch-data routes from routing table and also delete these components from components section. After all these changes, now go to navmenu.component.html file, remove Counter and Fetch Data items from the navmenu.component.html.
After all the changes given above, now our Application looks, as shown below.
Now, we add some components, which are required in this project.
Employee Detail Component
Now, we add the details component and using this component, we will display the details of an employee.
Right click on components folder, add a new folder and name this folder as details. This folder contains the content for the employee details component. Now, add a TypeScript file in this folder and name this file as details.component.ts and paste the code, as given below.
- import { Component } from '@angular/core';
-
- @Component({
- selector: 'employee-detail',
- templateUrl: './details.component.html'
- })
- export class DetailsComponent {
-
- }
Now, we need to add template file for this component fo which we are require to right click on details folder and an HTML file and name this file as details.component.html and paste the code given below.
- <h2>This is Detail Component</h2>
Edit Employee Component
In this project, we will provide the functionality to edit the details of any existing employee, for this we needs to add an “editEmployee” component. Thus, right click on components folder, add a new folder and name this folder as editEmployee. Now, add a TypeScript file and name this file as editEmployee.component.ts” and paste the code given below in it.
- import { Component } from '@angular/core';
-
- @Component({
- selector: 'edit-employee',
- templateUrl: './editEmployee.component.html'
- })
- export class editEmployeeComponent {
-
- }
Now, add HTML template file, name this file as editEmployee.component.html and paste the code given below.
New Employee Component
In this component, we write the code to enter a new entry for an employee. Right click on components folder and add newEmployee folder. Add a TypeScript file and name this file as newEmployee.component.ts and paste the code given below.
- import { Component } from '@angular/core';
-
- @Component({
- selector: 'new-employee',
- templateUrl: './newEmployee.component.html'
- })
- export class newEmployeeComponent {
-
- }
Now, add HTML template file and name this file as newEmployee.component.html and paste the code given below.
- <h1>This is New Employee component</h1>
After adding all the required components for the project, now structure of ClinetApp section looks, as shown below.
Add Routes for Components
After adding all the required components, now we need to perform the routing for these components. Open app.modules.ts file and paste the code given below into this file.
- import { NgModule } from '@angular/core';
- import { RouterModule } from '@angular/router';
- import { UniversalModule } from 'angular2-universal';
- import { AppComponent } from './components/app/app.component'
- import { NavMenuComponent } from './components/navmenu/navmenu.component';
- import { HomeComponent } from './components/home/home.component';
- import { DetailsComponent } from './components/details/details.component';
- import { newEmployeeComponent } from './components/newEmployee/newEmployee.component';
- import { editEmployeeComponent } from './components/editEmployee/editEmployee.component';
-
-
- @NgModule({
- bootstrap: [ AppComponent ],
- declarations: [
- AppComponent,
- NavMenuComponent,
- HomeComponent,
- DetailsComponent,
- newEmployeeComponent,
- editEmployeeComponent
- ],
- imports: [
- UniversalModule,
- RouterModule.forRoot([
- { path: '', redirectTo: 'home', pathMatch: 'full' },
- { path: 'home', component: HomeComponent },
- { path: 'details/:id', component: DetailsComponent },
- { path: 'new', component: newEmployeeComponent },
- { path: 'edit/:id', component: editEmployeeComponent },
- { path: '**', redirectTo: 'home' }
- ])
- ]
- })
- export class AppModule {
- }
In the code given above, we register all the components in declarations section and perform the routing for all these components.
Add new items in navmenu
Open navmenu.component.html file and paste the code given below in this file.
- <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']">EMS</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]="['/new']">
- <span class='glyphicon glyphicon-user'></span> New Employee
- </a>
- </li>
- </ul>
- </div>
- </div>
- </div>
In the code given above, we add New Employee item nav menu. By clicking this menu item, we can open New Employee page and add a new entry for an employee.
So far, we have created all the components. Also, we performed the routing and added a new item in nav menu. Let’s check that all these changes are working or not. When you run this Application, the screen given below will open.
When you click New Employee menu item, the screen given below will display.
Show Employee List
In our project’s home page, we will display the list of all the employees. We display the EmployeeName, Designation, Project information of an employee. First of all, we needs to create an API, using which we can get the list of all employee. Now, go to Controllers folder and a new API Controller, name this as EmployeeController and paste the code given below.
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading.Tasks;
- using Microsoft.AspNetCore.Http;
- using Microsoft.AspNetCore.Mvc;
- using EMS.Model;
- using EMS.ViewModel;
- using Microsoft.EntityFrameworkCore;
-
- namespace EMS.Controllers
- {
- [Produces("application/json")]
- [Route("api/Employee")]
- public class EmployeeController : Controller
- {
- private readonly EmployeeContext _context;
-
- public EmployeeController(EmployeeContext context)
- {
- _context = context;
- }
- [HttpGet]
- public async Task<IActionResult> EmployeeList()
- {
- List<Employee_Project> ilIst = new List<Employee_Project>();
- var listData = await (from emp in _context.Employee
- join pro in _context.Project on emp.ProjectId equals pro.ProjectId
- select new
- {
- emp.EmployeeId,
- emp.EmployeeName,
- emp.Designation,
- pro.ProjectName
-
- }
- ).ToListAsync();
- listData.ForEach(x =>
- {
- Employee_Project Obj = new Employee_Project();
- Obj.EmployeeId = x.EmployeeId;
- Obj.Designation = x.Designation;
- Obj.EmployeeName = x.EmployeeName;
- Obj.Project = x.ProjectName;
- ilIst.Add(Obj);
- });
-
- return Json(ilIst);
- }
- }
- }
In the lines of code given above, we create an asynchronous method. Asynchronous programming is a default mode of ASP.NET Core. Asynchronous programming provides a mechanism to write the code in non-blocking mode. We create an asynchronous EmployeeList method. In the first line of code, “List<Employee_Project> ilIst”, we create a list of “Employee_Project” ViewModel type. Here, “Employee_Project” is a ViewModel.
ViewModel in ASP.NET MVC is used to show only the required information., ViewModel is also used to show the data from two or more Models. Now, we add a ViewModel folder in the project. Add a new folder in the project and name it as ViewModels. After creating the viewModels folder, add a class in ViewModels folder. Right click on ViewModels folder and add a new class, name this class as Employee_Project. After creating the class, now paste the code given below in this class.
- namespace EMS.ViewModel
- {
- public class Employee_Project
- {
- public int EmployeeId { get; set; }
- public string EmployeeName { get; set; }
- public string Designation { get; set; }
- public string Project { get; set; }
- }
- }
Using LINQ query, we get EmployeeId, EmployeeName, Designation, ProjectName information about all the employees and add these values in iList object, using ForEach method. In the last line of code, we convert the ilist data into JSON format and return this JSON result to the required resource.
Now, our API is ready to return the employee list. Let’s check if it is working or not. Open your Browser, paste “http://localhost:54273/api/employee” URL and press enter. If you get the following JSON result, this means that our API is working perfectly.
Now, our API is ready to return the employee list. Let’s use this API and display the employee information. We need a Service, which can use this API and get the result. Add a Service folder in an app section. After creating the folder, add a TypeScript file and name this file as services.ts and paste the code given below into this file.
- import { Injectable } from '@angular/core';
- import { Http } from '@angular/http';
-
- @Injectable()
- export class EmployeeServcies {
- constructor(private http: Http) {
-
- }
- getEmployeeList() {
- return this.http.get('http://localhost:54273/api/employee');
- }
- }
In the code given above, we create an EmployeeServcies class and decorate this with @Injectable meta data. “@Injectbale meta data is used to define a class as a Service. In this Service class, we add getEmployeeList method. In this method, we are using GET method of HTTP class to perform HTTP GET request to the Server.
After creating the Service, now we need to register this Service in app.modules.ts file. Open your app.modules.ts file, import this Service and register this Service into providers. We are registering this Service in an app.modules.ts file, which means now this Service is a global Service. We can use this Service in any components and we don’t need to register this Service in each component.
After creating and registering the Service, now we use this Service in our home component, so open home.component.ts file and paste fthe code given below.
- import { Component } from '@angular/core';
- import { EmployeeServcies } from '../../Services/services';
- import { Response } from '@angular/http';
- @Component({
- selector: 'home',
- templateUrl: './home.component.html'
- })
- export class HomeComponent {
- public EmployeeList = [];
- public constructor(private empService: EmployeeServcies) {
- this.empService.getEmployeeList()
- .subscribe(
- (data: Response) => (this.EmployeeList= data.json())
- );
-
- }
- }
In the code given above, we create an instance(empService) of EmployeeServcies Service and use the getEmployeeList method of this Service to get the employee list. You can see that we are using a subscribe. Actually, an Angular 2 provides a new pattern to run asynchronous requests, which are knojwn as Observables, http is the successor to Angular 1's $http. Instead of returning a Promise, its http.get() method returns an Observable object. Using subscribe, method we can use the observable, the “subscribe” method tells the observable that you perform your task here is some one who listening and watching you. Perform the callback function when you return the result. In subscribe method, we get the data and assign the data into EmployeeList. Now, we use this list to display the employee list.
Open home.component.html file and paste the code given below.
- <div class="row">
- <div class="col-md-12">
- <h3>Employee List</h3>
- <br />
- <br />
- <br />
- </div>
-
- </div>
- <div class="row">
- <div class="table-responsive">
- <table class="table">
- <thead>
- <tr>
- <th>
- S.No.
- </th>
- <th>
- EmployeeName
- </th>
- <th>
- Designation
- </th>
- <th>
- Project
- </th>
- <th>
- Action
- </th>
- </tr>
- </thead>
- <tbody>
-
- <tr *ngFor="let empData of EmployeeList; let i = index; trackBy: employeeId">
- <td>
- {{i+1}}
- </td>
- <td>
- {{empData.employeeName}}
- </td>
- <td>
- {{empData.designation}}
- </td>
- <td>
- {{empData.project}}
- </td>
- <td>
-
- <a [routerLink]="['/details/',empData.employeeId]"
- class="btn btn-primary">
- Detail
- </a>
- <a [routerLink]="['/edit/',empData.employeeId]"
- class="btn btn-success">
- Edit
- </a>
- <a
- class="btn btn-danger">
- Delete
- </a>
- </td>
- </tr>
-
- </table>
- </div>
- </div>
In the code given above, we perform ngFor on an EmployeeList and create a list of employees. We also add three anchor tags (Edit, Delete and Detail) for an each employee entry. We use the routerLink to link the anchor tag to the specific part of our app.
After making all the changes, save the project and refresh the Browser and you will get the result given below.
Summary
This is the first part of SPA, using Angular 2, ASP.NET Core 1.1 and Entity Framework Core series. Today, we learned how to setup.NET Core project with Angular 2 and also understand the structure of the project. We also performed the setup for EF Core(Entity Framework) in this project. We created some component and performed the routing for these components. Create Service to get the data from Web API, using builtin http Service and display these data into a tabular format. In the next article, we will create some screens to add, delete or edit the employee information. We also provide the functionality of searching and sorting employee information.