This article provides a brief info to setup ASP.NET Core project with Angular 2. We will create an Employee Management System (EMS) to understand the Concept of Angular2 along with ASP.NET Core.
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 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 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
Pre Requests
There is some minimum configuration that must be done on your system before starting the work on this series:
- Visual Studio 2015 Update 3 or Visual Studio 2017
- .NET Core 1.0
- Type Script 2.0
- Node.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 that is made available. These plug into the standard dotnet new command, and work on Windows, Mac, and Linux. To install the (Single Page Application)SPA templates, open the command prompt and run the following command.
dotnet new --install Microsoft.AspNetCore.SpaTemplates::*
The above command takes some time and installs the several templates for SPA like Angular, Knockout.js, React, etc. The benefit of all these templates is that we don’t need to be worried about the whole setup process.
To generate a new project, first of all, 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 following command dotnet new angular
.
This command creates a template project for Angular 2 application. Now run dotnet restore
command, this command builds the MSBuild file and restores all the .NET dependencies.
After installing all the .NET dependencies, now we install Node.js dependencies. Run npm install
command, this command takes a 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! You successfully created the 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, you will find the below project structure.
Following are the major parts of our application.
Dependencies
This section contains three types of the dependencies "npm" dependencies are related to our Client application and "NuGet" contains the .NET Core level dependencies. "SDK" section contains system level dependencies.
launchSettings.json
This json file holds project specific settings associated with each debug profile, Visual Studio is configured to use to launch the application, including any environment variables that 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 ClientApp
. All the code that we write in template(.ts) or .html pages convert 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 that we create in our ClientApp folder.
If you go to Index.cshtml view of Home
controller, you will find that we referenced the main-client.js file in the 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 the client section of our project. Here, we write all the Angular2 related code and 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 data from the database.
Views
It defines V part of the MVC project, I think we are already aware with 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, 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 provides all the services that system requires to run.
tsconfig.cs
This file contain Type Script 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 that represent 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 the Entity Framework for SQL Server. To configure the Entity Framework for SQL Server, we needs to add the SQL Server database provider.
Open Package Manager Console and run the following command:
Install-Package Microsoft.EntityFrameworkCore.SqlServer
We will be using some Entity Framework Tools to maintain the database. So we need to install the tools packages as well. So run the below command to add all 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 many to one relationship between Employee
and Project
entity, that means one employee can have only one project at a time, but there can be more than one employees in a single project. First, create a Model folder and add Employee
class in this folder.
Employee Entity
Add an Employee
class in Models folder and replace the code of Employee
class with the following code:
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 above code, EmployeeId
property is the primary key for the Employee
entity and it is also 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 as Project
, replace the code of this class with the following code:
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 the primary key for this entity and other properties define the information about the project.
Add DbContext Class
The main class of any Entity Framework structure is DbContext
class. In this class, we define all the entities that 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 in this class with the following code.
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 above code, we defined two Dbset
properties for Employee
and Project
class. This property will create two tables in database and name will be same as defined in Dbset
property.
Register Context with Dependency Injection
After creating all entity and dbContext
classes, now we add a service for Entity Framework such that any component that requires this service 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 following code to ConfigureServices
method.
services.AddDbContext<EmployeeContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
In the above code, we register a service for DbContext
, here DefaultConnection
providing the connection string that is defined in our appsettings.json. Now open your appsettings.json file and add the following code. 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 Database
After configuring dbContext
and entity classes, now we add the migration and using the Update-Database
command, we will create our project database. So first, we add the migration, for this 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 information about how to create your database.
Now we will run Update-Database
command, this command takes codes available in migration class and updates your database. In our case, this command creates an Employee
database in SQL Server that contains the all table and properties that we defined earlier in our model classes.
Now open your SQL Server, you will find that Employee
database has been added.
Add Initial Data
Now our tables and database is 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) )
Add Data into 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 application setup is ready, let’s start work with View section of 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 of 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 and remove "Counter
" and "Fetch Data
" items from the navmenu.component.html.
After all the above changes, now our application looks as below:
Now we add some components that are required in this project.
Employee Detail Component
Now we add a details component and using this component, we will display the details of an employee.
Right click on components folder and add a new folder and name this folder as details. This folder contains the content for employee details component. Now add a typescript file in this folder and name this file as details.component.ts and paste the following:
import { Component } from '@angular/core';
@Component({
selector: 'employee-detail',
templateUrl: './details.component.html'
})
export class DetailsComponent {
}
Now we need a template file for this component, so right click on details folder and an html file and name this file as details.component.html and paste the following code:
<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 need to add an editEmployee
component. So, right click on components folder and add a new folder and named this folder as editEmployee. Now add a typescript file and name this file as editEmployee.component.ts and paste the following code:
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 following code:
<h1>Edit Employee</h1>
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 named this file as newEmployee.component.ts and paste the following code:
import { Component } from '@angular/core';
@Component({
selector: 'new-employee',
templateUrl: './newEmployee.component.html'
})
export class newEmployeeComponent {
}
Now add an html template file and name this file as newEmployee.component.html and paste the following code:
<h1>This is New Employee component</h1>
After adding all the required components for project, now structure of ClientApp
section looks as below:
Add Routes for Components
After adding all the required components, now we perform the routing for these components. Open app.modules.ts file and paste the following code 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 above code, 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 following code 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 above code, we add New Employee
item nav menu. Clicking this menu item, we can open New Employee page and add a new entry for an employee.
Till now, we have been created all the components, also perform the routing and add a new item in nav menu. Let’s check whether all these changes are working or not. When you run this application, the following screen will open:
When you click on New Employee menu item, the following screen will display:
Show Employee List
In our project’s home page, we will display the list of all employees. We display the EmployeeName
, Designation
, Project
information of an employee. First of all, we need to create an API, using that, we can get the list of all employees. Now go to Controllers folder and a new "API Controller", name this as EmployeeController
and paste the following code:
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 above lines of code, we create an asynchronous method. Asynchronous programming is the 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 required information, ViewModel
is also used to show data from two or more models. Now we add a ViewModel folder in project. Add a new folder in project and named as ViewModels. After creating the viewModels folder, add a class in ViewModels folder. Right click on ViewModels folder and add a new class, named this class as Employee_Project
. After creating the class, now paste the following code 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 employees and add these value 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 required resource.
Now our API is ready to return the employee list, let’s check that it is working or not. Open your browser and paste http://localhost:54273/api/employee URL and press enter. If you get the following JSON result, that means 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 needs a service that can use this API and get the result. Add a Service folder in app section. After creating the folder, add a typescript file and name this file as services.ts and paste the following code 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 above code, we create an EmployeeServcies
class and decorate this with @Injectable
meta data. @Injectable
meta data is used to define a class as service. In this service class, we add getEmployeeList
method, in this method, we are using the get
method of HTTP
class to perform the HTTP get
request to server.
After creating the service, now we need to register this service in "app.modules.ts" file. Open your app.modules.ts file and import this service and register this service into providers. We are registering this service in app.modules.ts file, that means now this service is global service, we can use this service in any component 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 the following code:
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 above code, we create an instance(empService)
of EmployeeServices
service and use the getEmployeeList
method of this service to get the employee list. You can see that we are using a subscribe
. Actually, Angular 2 provides a new pattern for running asynchronous requests, called 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 someone who is listing and watching you, and perform that 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 following code:
<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 above code, we perform the *ngFor
on EmployeeList
and create a list of employees. We also add three anchor tags (Edit, Delete and Detail) for each employee entry. We use the routerLink
to link the anchor tag to specific part of our app.
After making all the changes, now save the project and refresh the browser, you will get the following result:
Summary
This is the first part of "SPA Using Angular 2, ASP.NET Core 1.1 and Entity Framework Core" series. Today, we learnt how to setup .NET Core project with Angular2 and also understood 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. We created service to get the data from Web API using inbuilt "http" service and displayed this 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 search and sorting employee information.
History
- 4th April, 2017: Initial version