Click here to Skip to main content
14,122,006 members
Click here to Skip to main content
Add your own
alternative version

Stats

14.9K views
15 bookmarked
Posted 4 Apr 2017
Licenced CPOL

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

Rate this:
Please Sign up or sign in to vote.
This article provide a brief info to setup ASP.NET core project with Angular 2. We will create a Employee Management System(EMS) to understand the Concept of Angular2 along with ASP.NET Core.

Introduction

This is 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 employee, 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 some minimum configuration that 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
  • 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 are 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 following command.

dotnet new --install Microsoft.AspNetCore.SpaTemplates::*

Above command take some time and install the several templates for SPA like Angular, Knockout.js , React etc. The benefit of all these templates are that we don’t need worried about the whole setup process.

To generate a new project first of all create and empty folder and named this project as "EMS" here EMS is abbreviation for "Employee Management System. After creating an empty folder now change the directory and go to this project. Now run following command "dotnet new angular".

This command create a template project for Angular 2 application. Now run "dotnet restore" commanpm nd, this command build the "MSBuild" file and restore all the .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 run the project if you get 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 run the application successfully let’s understand the structure of the project. Now open "Solution Explorer" window, you will find 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 define applicationURl, SSL port number and mode of authentication.

wwwroot

wwwroot section contains the "dist" folder, here dist folder contain the compiled code of our "ClinetApp". 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 contain 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 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 the Angular2 related code and create component and services. App folder contain components and "app.module.ts" file. The "boot-client.ts" file define 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 contain all Angular2 related dependencies.

Program.cs

This is entry point of the application, use 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 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 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 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 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 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 b/w 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 above code, EmployeeId property is 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 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 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 DbCntext 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 named as "EmployeeContext". This class will be derived from "System.Data.Entity.DbContext" class. Replace the code this class with 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 define 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 require 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 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 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 contain all information how to create your database.

Now we will run "Update-Database" command, this command take codes available in migration class and updates your database. In our case this command create 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 found that "Employee" database has been added.

Add initial data

Now our tables and database is ready let’s add some initials 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 component 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 require 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 named this folder as "details". This folder contain the content for employee details component. Now add a typescript file in this folder and named this file as "details.component.ts" and paste following.

import { Component } from '@angular/core';

@Component({
    selector: 'employee-detail',
    templateUrl: './details.component.html'
})
export class DetailsComponent {
    
}

Now we needs to a template file for this component, so right click on "details" folder and an html file and named this file as "details.component.html" and paste 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 needs 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 named this file as "editEmployee.component.ts" and paste following code.

import { Component } from '@angular/core';

@Component({
    selector: 'edit-employee',
    templateUrl: './editEmployee.component.html'
})
export class editEmployeeComponent {

}

Now add html template file, named this file as "editEmployee.component.html" and paste 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 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 named this file as "newEmployee.component.html" and paste following code.

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

After adding all the required components for project, now structure of "ClinetApp" 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 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, // 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 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 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 that all these changes working or not. When you run this application following screen will open.

When you click on "New Employee" menu item 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 needs to create an API, using that we can get the list of all employee. Now go to "Controllers" folder and a new "API Controller", named 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 above lines of code we create an asynchronous method. Asynchronous programming is default mode of Asp.Net Core. Asynchronous programming provide 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 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 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’ check that it is working or not. Open your browser and paste "http://localhost:54273/api/employee" URL and press enter. If you get following JSON result that means our API 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 named this file as "services.ts" and paste 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 above code we create an "EmployeeServcies" class and decorate this with "@Injectable" meta data. "@Injectbale meta data is sued to defined 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 needs 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 register this service in "app.modules.ts" file that means now this service is 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 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 above code 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 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 tell the observable that "you perform your task here is some one who 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 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 following result.

Summary

This is first part of "SPA Using Angular 2, Asp.Net Core 1.1 and Entity Framework Core" series. Today we learn how to setup.net core project with Angular2 and also understand the structure of the project. We also perform the setup for EF Core(Entity Framework) in this project. We create some component and perform the routing for these components. Create service to get the data from Web API using inbuilt "http" service and display these data into a tabular format. In 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.

License

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

Share

About the Author

Pankaj Kumar Choudhary
Student
India India
Pankaj Kumar Choudhary loves Microsoft and Database technologies. He has experience on several database technology like SQL Server, MySQL, Oracle, MongoDB, PostgreSQL . He has knowledge of several technology like Asp.Net MVC, Entity Framework , Android, Php, AngularJS, Node.js, Angular2, React, Ionic and Android.

You may also be interested in...

Pro

Comments and Discussions

 
QuestionDisplayed web page error Pin
Member 135038568-Nov-17 23:21
memberMember 135038568-Nov-17 23:21 
PraiseGreat article....... Pin
sodangbe31-Oct-17 11:19
membersodangbe31-Oct-17 11:19 
QuestionPart 2 - where? Pin
Member 1345743110-Oct-17 10:37
memberMember 1345743110-Oct-17 10:37 
QuestionThanks! Pin
MatsNordin12-Apr-17 22:03
memberMatsNordin12-Apr-17 22:03 
Questionsecurity Pin
tlang337-Apr-17 13:08
membertlang337-Apr-17 13:08 
AnswerRe: security Pin
George Lanes10-Apr-17 9:39
memberGeorge Lanes10-Apr-17 9:39 
AnswerRe: security Pin
Super Superman11-Jul-17 2:45
memberSuper Superman11-Jul-17 2:45 
SuggestionApp folder and file structure Pin
George Lanes5-Apr-17 19:06
memberGeorge Lanes5-Apr-17 19:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Cookies | Terms of Use | Mobile
Web04 | 2.8.190518.1 | Last Updated 4 Apr 2017
Article Copyright 2017 by Pankaj Kumar Choudhary
Everything else Copyright © CodeProject, 1999-2019
Layout: fixed | fluid