Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / C#6.0

SPA Using Angular 2, ASP.NET Core 1.1 and Entity Framework Core (Part 1)

4.72/5 (13 votes)
4 Apr 2017CPOL14 min read 24.8K  
How to setup ASP.NET Core project with Angular 2
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::*

Image 1

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.

Image 2

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.

Image 3

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.

Image 4

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.

Image 5

Image 6

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.

Image 7

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.

Image 8

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.

ASP.NET
@{
    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.

Image 9

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:

C#
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:

C#
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.

C#
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.

JavaScript
services.AddDbContext<EmployeeContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

Image 10

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.

JavaScript
{
  "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.

Image 11

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.

Image 12

Add Initial Data

Now our tables and database is ready, let’s add some initial data into our tables.

Add Data into Project Table

SQL
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) )

Image 13

Add Data into Employee Table

SQL
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')

Image 14

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:

Image 15

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.

Image 16

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:

TypeScript
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:

ASP.NET
<h2>This is Detail Component</h2>

Edit Employee Component

Image 17

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:

TypeScript
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:

HTML
<h1>Edit Employee</h1>

New Employee Component

Image 18

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:

TypeScript
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:

HTML
<h1>This is New Employee  component</h1>

After adding all the required components for project, now structure of ClientApp section looks as below:

Image 19

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:

TypeScript
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, // Must be first import. This automatically 
                         // imports BrowserModule, HttpModule, and JsonpModule too.
        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:

HTML
<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:

Image 20

When you click on New Employee menu item, the following screen will display:

Image 21

Show Employee List

Image 22

In our project’s home page, we will display the list of all employees. We display the EmployeeNameDesignation, 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:

JavaScript
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:

JavaScript
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.

Image 23

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:

TypeScript
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.

Image 24

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:

TypeScript
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:

HTML
<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:

Image 25

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)