CRUD In Web API, Using .NET Core And AngularJS2

In our previous article, we have seen how to startup with .NET Core. In this article, we will take a look at database operations according to previous sample applications based on previous concepts.

If you are new to .NET Core, please read my previous post about .Net Core Startup

In this article, we are going to explore the following:

  1. Create Database
  2. Use Entity Framework Core (Db First Approach),
    • Overview EF Core
    • Install Entity Framework
    • Create Models
    • Configure EF Service
  3. Use MVC 6
    • Overview MVC6
    • Use WebAPI 
  4. Use AngularJS2
    • Component, 
    • Route
    • Service
  5. Configure Server
    • Run App inside/outside IIS

Let’s get started.

Create Database

Before we get started with IDE, let's create a new database using SSMS 2014 (SQL Server Management System). Name it as PhoneBook.

PhoneBook

Create a table named Contacts, copy & run the below script in SSMS 2014:

  1. USE [PhoneBook]  
  2. GO  
  3.   
  4. /****** Object: Table [dbo].[Contacts] Script Date: 8/7/2016 11:28:55 AM ******/  
  5. SET ANSI_NULLS ON  
  6. GO  
  7.   
  8. SET QUOTED_IDENTIFIER ON  
  9. GO  
  10.   
  11. CREATE TABLE [dbo].[Contacts](  
  12. [ContactID] [int] IDENTITY(1,1) NOT NULL,  
  13. [FirstName] [nvarchar](50) NULL,  
  14. [LastName] [nvarchar](50) NULL,  
  15. [Phone] [nvarchar](50) NULL,  
  16. [Email] [nvarchar](50) NULL,  
  17. CONSTRAINT [PK_Contacts] PRIMARY KEY CLUSTERED   
  18. (  
  19. [ContactID] ASC  
  20. )WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ONON [PRIMARY]  
  21. ON [PRIMARY]  
  22.   
  23. GO  
Following our previous topic, I am going to use previous sample application. Open it with Visual Studio 2015.

sample

It will automatically start restoring the dependencies. Build & run it. The application is working perfectly.

Install Entity Framework: Before installation, let’s have an overview on EF Core new features
  • Modelling: This includes Basic Modelling, Data Annotations, Relationships, and much more.
  • Change Tracking: This includes Accessing tracked state, Snapshot, Notification change tracking.
  • SaveChanges: This includes Basic save functionality, Async SaveChanges,Transactions.
  • Query: This includes Basic LINQ support, Async query, Raw SQL queries
  • Database schema management: This includes database creation/deletion, APIs, Relational database migrations, and Reverse engineering from database.
  • Database providers: This includes EntityFramework, SQL Server, Sqlite, InMemory
  • Platforms: Supports Universal Windows Platform (UWP), .NET Core, Full .NET

Get more details about EF Core.

Let’s add folders for Entity models in our sample app solution.

folders

DbEntities: for model entities.

The installation of EF is pretty much simple. Open project.json file, point tools section, modify the section with below lines.

  1. "Microsoft.EntityFrameworkCore.SqlServer""1.0.0",  
  2. "Microsoft.EntityFrameworkCore.Tools""1.0.0-preview2-final",  
  3. "Microsoft.EntityFrameworkCore.SqlServer.Design""1.0.0"  
ef

Save changes after modification.

modification

Packages will be automatically restored. Let’s get an explanation of what those are.

EntityFrameworkCore.SqlServer: Database Provider, that allows Entity Framework Core to be used with Microsoft SQL Server.

EntityFrameworkCore.Tools: Command line tool for EF Core. Includes Commands
 
For Package Manager Console
  • Scaffold-DbContext,
  • Add-Migration,
  • Udate-Database

For Command Window

  • dotnet ef dbcontext scaffold

We will see how to use both commands.

EntityFrameworkCore.SqlServer.Design: Design-time that allows Entity Framework Core functionality (EF Core Migration) to be used with Microsoft SQL Server.

To access the Command line tools. we need to add EntityFrameworkCore.Tools in tools section of our project.json.

"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final"


code

Save changes after modification.

Command in Package Manager Console: Open Package Manager console.

tools

Input the following commands and hit enter.

Scaffold-DbContext "Server=DESKTOP-4T79RA1;Database=PhoneBook;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models/DbEntities

command

command

Command in Command Window: Open Command Window, navigate to project directory, and type,

D:\Article\ASP-CORE\CRUD\CoreMVCAngular2\src\CoreMVCAngular>dotnet ef –help

Here, a list of options will be shown in command window. We are going to use dbcontext in Commands.

Commands

Next, input the below command and hit enter,

D:\Article\ASP-CORE\CRUD\CoreMVCAngular2\src\CoreMVCAngular>dotnet ef dbcontext scaffold "Server=DESKTOP-4T79RA1;Database=PhoneBook;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer --output-dir Models/CwEntities


Commands

Here is a screenshot of both processes that execute & generate models. We will keep DbEntities folder to work with & will delete the other folder.

folder

Configure EF Service

In PhoneBookContext Class, add constructor.

  1. public PhoneBookContext(DbContextOptions<PhoneBookContext> options) :  
  2. base(options)  
  3. {  
  4. }  
In Startup class, we need to enable EF services providing the connectionstring to,
  1. public void ConfigureServices(IServiceCollection services) {  
  2.     services.AddMvc();  
  3.     var connection = @ "Server=DESKTOP-4T79RA1;Database=PhoneBook;Trusted_Connection=True;";  
  4.     services.AddDbContext < PhoneBookContext > (options => options.UseSqlServer(connection));  
  5. }  
We have configured the EF services in our application. Next, we will work with MVC 6 that is included in ASP.NET Core.

MVC 6: We have already discussed about MVC 6 in our previous post. Let's have an overview on MVC 6 new features, once again: 
  1. MVC+Web API+Web Pages = MVC6
  2. No System.Web
  3. Web pages & HTTP services is Unified
  4. Dependency injection built in
  5. Dynamic code compilation (Roslyn compiler)
  6. Open source &
  7. Support cross-platform build & run.
  8. Can be hosted in IIS or self-hosted(Outside IIS)

OK. Now, let’s add a WebAPI Controller to perform the CRUD operation to database table.

WebApi Controller

In Solution Explorer, add a new API folder. Right click on it > Add New Item > Web API Controller Class > Add. Modify the initial template.

API Controller

  1. [Route("api/[controller]")]  
  2. public class ContactController: Controller {  
  3.     private PhoneBookContext _ctx = null;  
  4.     public ContactController(PhoneBookContext context) {  
  5.         _ctx = context;  
  6.     }  
  7. }  
API Controller

You may have noticed that there is a new pattern [ ] in MVC 6 attribute route, [RouteToken]. This means that the route token has automatically taken the controller name.

Like [Route("api/[controller]")] > [Route("api/Contact")]

Another thing, we know Web API produces XML by default. Now, in MVC 6, we can set an attribute to change the default produces to JSON type by putting attribute in Class label or on method label. In our case, we have set it on method label.

[HttpGet("GetContact"), Produces("application/json")]

GET
  1. // GET: api/Contact/GetContact  
  2. [HttpGet("GetContact"), Produces("application/json")]  
  3. public async Task<object> GetContact()  
  4. {  
  5.     List<Contacts> contacts = null;  
  6.     object result = null;  
  7.     try  
  8.     {  
  9.         using (_ctx)  
  10.         {  
  11.             contacts = await _ctx.Contacts.ToListAsync();  
  12.             result = new  
  13.             {  
  14.                 contacts  
  15.             };  
  16.         }  
  17.     }  
  18.     catch (Exception ex)  
  19.     {  
  20.         ex.ToString();  
  21.     }  
  22.     return result;  
  23. }  
POST
  1. // POST api/Contact/PostContact  
  2. [HttpPost, Route("PostContact")]  
  3. public async Task<object> PostContact([FromBody]Contacts model)  
  4. {  
  5.     object result = nullint message = 0;  
  6.     if (model == null)  
  7.     {  
  8.         return BadRequest();  
  9.     }  
  10.     using (_ctx)  
  11.     {  
  12.         using (var _ctxTransaction = _ctx.Database.BeginTransaction())  
  13.         {  
  14.             try  
  15.             {  
  16.                 _ctx.Contacts.Add(model);  
  17.                 await _ctx.SaveChangesAsync();  
  18.                 _ctxTransaction.Commit();  
  19.                 message = (int)responseMessage.Success;  
  20.             }  
  21.             catch (Exception e)  
  22.             {  
  23.                 _ctxTransaction.Rollback();  
  24.                 e.ToString();  
  25.                 message = (int)responseMessage.Error;  
  26.             }  
  27.   
  28.             result = new  
  29.             {  
  30.                 message  
  31.             };  
  32.         }  
  33.     }  
  34.     return result;  
  35. }  
PUT
  1. // PUT api/Contact/PutContact/5  
  2. [HttpPut, Route("PutContact/{id}")]  
  3. public async Task<object> PutContact(int id, [FromBody]Contacts model)  
  4. {  
  5.     object result = nullint message = 0;  
  6.     if (model == null)  
  7.     {  
  8.         return BadRequest();  
  9.     }  
  10.     using (_ctx)  
  11.     {  
  12.         using (var _ctxTransaction = _ctx.Database.BeginTransaction())  
  13.         {  
  14.             try  
  15.             {  
  16.                 var entityUpdate = _ctx.Contacts.FirstOrDefault(x => x.ContactId == id);  
  17.                 if (entityUpdate != null)  
  18.                 {  
  19.                     entityUpdate.FirstName = model.FirstName;  
  20.                     entityUpdate.LastName = model.LastName;  
  21.                     entityUpdate.Phone = model.Phone;  
  22.                     entityUpdate.Email = model.Email;  
  23.   
  24.                     await _ctx.SaveChangesAsync();  
  25.                 }  
  26.                 _ctxTransaction.Commit();  
  27.                 message = (int)responseMessage.Success;  
  28.             }  
  29.             catch (Exception e)  
  30.             {  
  31.                 _ctxTransaction.Rollback(); e.ToString();  
  32.                 message = (int)responseMessage.Error;  
  33.             }  
  34.   
  35.             result = new  
  36.             {  
  37.                 message  
  38.             };  
  39.         }  
  40.     }  
  41.     return result;  
  42. }  
DELETE
  1. // DELETE api/Contact/DeleteContactByID/5  
  2. [HttpDelete, Route("DeleteContactByID/{id}")]  
  3. public async Task<object> DeleteContactByID(int id)  
  4. {  
  5.     object result = nullint message = 0;  
  6.     using (_ctx)  
  7.     {  
  8.         using (var _ctxTransaction = _ctx.Database.BeginTransaction())  
  9.         {  
  10.             try  
  11.             {  
  12.                 var idToRemove = _ctx.Contacts.SingleOrDefault(x => x.ContactId == id);  
  13.                 if (idToRemove != null)  
  14.                 {  
  15.                     _ctx.Contacts.Remove(idToRemove);  
  16.                     await _ctx.SaveChangesAsync();  
  17.                 }  
  18.                 _ctxTransaction.Commit();  
  19.                 message = (int)responseMessage.Success;  
  20.             }  
  21.             catch (Exception e)  
  22.             {  
  23.                 _ctxTransaction.Rollback(); e.ToString();  
  24.                 message = (int)responseMessage.Error;  
  25.             }  
  26.   
  27.             result = new  
  28.             {  
  29.                 message  
  30.             };  
  31.         }  
  32.     }  
  33.     return result;  
  34. }  
So, our Web API is ready for dealing with the data to database. It’s the time to work with client side scripting.

AngularJS2

Our WebAPI is ready to deal with the data from server. Now, we are going to work in client-side code with typescript (.ts) files.

First of all, we need to create a Master page to present our views in it.

AngularJS2

Then, we need to point this HTML file while app starts. So, let’s go to the startup.cs file to add below code snippet.

This is the configuration for the default files Middleware.

Startup.cs
  1. // app-specific root page(Index.html)  
  2. DefaultFilesOptions options = new DefaultFilesOptions();  
  3. options.DefaultFileNames.Clear();  
  4. options.DefaultFileNames.Add("/Index.html");  
  5. need to add library   
  6. using Microsoft.AspNetCore.Builder;   
  7. Now add script library reference to the html page & define view point to load our app component views.  
  8. <spa-app>  
  9. <p>  
  10. <img src="img/ajax_small.gif" /> Please wait ...  
  11. </p>  
  12. </spa-app>  
Then, we need to reference our bootstrap file in our page that imports & enables our Angular script to the page.
  1. <script>  
  2.     System.config({  
  3.         packages: {  
  4.             'app': {  
  5.                 defaultExtension: 'js'  
  6.             }  
  7.         },  
  8.     });  
  9.     System.import('app/main').then(null, console.error.bind(console));  
  10. </script>  
Let’s put together all those in Index.html file.

Index.html

  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4.     <meta charset="utf-8" />  
  5.     <meta name="viewport" content="width=device-width" />  
  6.     <title></title>  
  7.   
  8.     <base href="/">  
  9.     <script>document.write('<base href="' + document.location + '" />');</script>  
  10.     <script src="../lib-npm/es6-shim/es6-shim.js"></script>  
  11.     <script src="../lib-npm/angular2/angular2-polyfills.js"></script>  
  12.     <script src="../lib-npm/systemjs/system.src.js"></script>  
  13.     <script src="../lib-npm/rxjs/Rx.js"></script>  
  14.     <script src="../lib-npm/angular2/angular2.js"></script>  
  15.     <script src="../lib-npm/angular2/router.js"></script>  
  16.     <script src="../lib-npm/angular2/http.js"></script>  
  17.   
  18.     <link href="../lib/bootstrap/dist/css/bootstrap.min.css" rel="stylesheet" />  
  19. </head>  
  20. <body>  
  21.     <div class="container">  
  22.         <spa-app>  
  23.             <p>  
  24.                 <img src="img/ajax_small.gif" />  Please wait ...  
  25.             </p>  
  26.         </spa-app>  
  27.   
  28.     </div>  
  29.     <script src="../lib/jquery/dist/jquery.min.js"></script>  
  30.     <script src="../lib/bootstrap/dist/js/bootstrap.min.js"></script>  
  31.     <script>  
  32.         System.config({ packages: { 'app': { defaultExtension: 'js' } }, });  
  33.         System.import('app/main').then(null, console.error.bind(console));  
  34.     </script>  
  35. </body>  
  36. </html>  
Bootstrap, Model, Component & Route

Main.ts
  1. /*This is the spa bootstrap File*/  
  2.   
  3. //---------Import Angular2------------  
  4. import {bootstrap} from 'angular2/platform/browser';  
  5. import {enableProdMode, provide} from 'angular2/core';  
  6.   
  7. //---------Import External Components(Main Component)---------  
  8. import {MainComponent} from './app.component';  
  9.   
  10. //---------Bootstrap Component---------  
  11. enableProdMode();  
  12. bootstrap(MainComponent);  
App.component.ts
  1. /*Component Default view For SpaRoute */  
  2.   
  3. //---------Import Angular2------------  
  4. import {Component, provide} from 'angular2/core';  
  5. import {RouteConfig, ROUTER_DIRECTIVES, ROUTER_PROVIDERS, LocationStrategy, HashLocationStrategy, APP_BASE_HREF} from 'angular2/router';  
  6.   
  7. //---------Import External Components---------  
  8. import {Home} from './home/home.component';  
  9. import {Contact} from './contact/contact.component';  
  10.   
  11. //---------Declare Components---------  
  12. @Component({  
  13. selector: 'spa-app',  
  14. directives: [ROUTER_DIRECTIVES], //decorate link   
  15. templateUrl: 'app/main.view.html',  
  16. providers: [  
  17. ROUTER_PROVIDERS,  
  18. //provide(APP_BASE_HREF, { useValue: '/' })  
  19. provide(LocationStrategy, { useClass: HashLocationStrategy })  
  20. ]  
  21. })  
  22.   
  23. //---------Declare Route Config---------  
  24. @RouteConfig([  
  25. { path: '/', name: 'Home', component: Home, useAsDefault: true },  
  26. { path: '/Contact/...', name: 'Contact', component: Contact }  
  27. ])  
  28.   
  29.   
  30. //---------Export This Component Class---------  
  31. export class MainComponent {  
  32. title: string;  
  33. constructor() {  
  34. this.title = 'Welcome to [.NetCore+MVC6+Angular2] SPA';  
  35. }  
  36. }  
Home.ts
  1. import {  
  2.     Component  
  3. } from 'angular2/core';  
  4. @Component({  
  5.     selector: 'home',  
  6.     templateUrl: `app/home/home.view.html`  
  7. })  
  8. export class Home {  
  9.     constructor() {}  
  10. }  
Contact.model.ts
  1. export class ContactModel {  
  2.     contactId: number;  
  3.     firstName: string;  
  4.     lastName: string;  
  5.     phone: string;  
  6.     email: string;  
  7. }  
Contact.component.ts
  1. //---------Import Angular2------------  
  2. import {  
  3.     Component  
  4. } from 'angular2/core';  
  5. import {  
  6.     ROUTER_DIRECTIVES,  
  7.     RouteConfig  
  8. } from 'angular2/router';  
  9. //---------Import External Components---------  
  10. import {  
  11.     ContactMain  
  12. } from './contact.main';  
  13. //---------Declare Components---------  
  14. @Component({  
  15.     selector: 'contacts',  
  16.     template: `<router-outlet></router-outlet>`,  
  17.     directives: [ROUTER_DIRECTIVES]  
  18. })  
  19. @RouteConfig([{  
  20.     path: '/',  
  21.     name: 'ManageContact',  
  22.     component: ContactMain,  
  23.     useAsDefault: true  
  24. }, ])  
  25. export class Contact {  
  26.     constructor() {}  
  27. }  
Contact.main.ts
  1. //---------Import Angular2------------  
  2. import {  
  3.     Component,  
  4.     OnInit  
  5. } from 'angular2/core';  
  6. import {  
  7.     HTTP_PROVIDERS,  
  8.     Http  
  9. } from 'angular2/http';  
  10. import {  
  11.     ROUTER_DIRECTIVES,  
  12.     RouteConfig  
  13. } from 'angular2/router';  
  14. import {  
  15.     FORM_DIRECTIVES,  
  16.     FormBuilder,  
  17.     Control,  
  18.     ControlGroup,  
  19.     Validators  
  20. } from 'angular2/common';  
  21. //---------Import External Components---------  
  22. import {  
  23.     ContactModel  
  24. } from './contact.model';  
  25. import {  
  26.     ContactService  
  27. } from './contact.service';  
  28. import {  
  29.     customvalidators  
  30. } from './customvalidators';  
  31. //---------Declare Components---------  
  32. @Component({  
  33.         selector: 'contact-list',  
  34.         templateUrl: `app/contact/contact.view.html`,  
  35.         directives: [ROUTER_DIRECTIVES, FORM_DIRECTIVES],  
  36.         providers: [ContactService, HTTP_PROVIDERS]  
  37.     })  
  38.     //---------Export This Component Class---------  
  39. export class ContactMain implements OnInit {  
  40.     public resmessage: string;  
  41.     public addmessage: string;  
  42.     public listmessage: string;  
  43.     public contact: ContactModel;  
  44.     public contacts: ContactModel[];  
  45.     public editContactId: any  
  46.         //Form Control  
  47.     contactForm: ControlGroup;  
  48.     firstName: Control;  
  49.     email: Control;  
  50.     phone: Control;  
  51.     //Constructor  
  52.     constructor(private builder: FormBuilder, private contactService: ContactService) {  
  53.         this.addmessage = 'Add New Contact';  
  54.         this.listmessage = 'All Contact';  
  55.         this._formGroup();  
  56.     }  
  57.     ngOnInit() {  
  58.             this.resmessage = "";  
  59.             this.editContactId = 0;  
  60.             this.getContacts();  
  61.         }  
  62.         //Form Group  
  63.     _formGroup() {  
  64.             this.firstName = new Control('', Validators.required);  
  65.             this.email = new Control('', Validators.compose([Validators.required, customvalidators.emailValidator]));  
  66.             this.phone = new Control('');  
  67.             this.contactForm = this.builder.group({  
  68.                 firstName: this.firstName,  
  69.                 email: this.email,  
  70.                 phone: this.phone  
  71.             });  
  72.         }  
  73.         //Get All   
  74.     getContacts() {  
  75.             //debugger  
  76.             this.contactService.getContacts().subscribe(contacts => this.contacts = contacts);  
  77.         }  
  78.         //Save Form  
  79.     saveContact(contact) {  
  80.             //debugger  
  81.             this.contactService.saveContact(contact).subscribe(response => {  
  82.                 this.resmessage = response;  
  83.                 this.getContacts();  
  84.                 this.reset();  
  85.             });  
  86.         }  
  87.         //Get by ID  
  88.     editContact(e, m) {  
  89.             //debugger  
  90.             e.preventDefault();  
  91.             this.editContactId = m.contactId;  
  92.             this.contactService.getContactByID(m.contactId).subscribe(response => {  
  93.                 this.contact = response;  
  94.                 this.firstName.updateValue(this.contact.firstName);  
  95.                 this.email.updateValue(this.contact.email);  
  96.                 this.phone.updateValue(this.contact.phone);  
  97.             });  
  98.         }  
  99.         //Save Form  
  100.     updateContact(contact: any) {  
  101.             //debugger  
  102.             if (this.editContactId > 0) {  
  103.                 this.contactService.updateContact(contact, this.editContactId).subscribe(response => {  
  104.                     this.resmessage = response;  
  105.                     this.getContacts();  
  106.                     this.reset();  
  107.                 });  
  108.             }  
  109.         }  
  110.         //Delete  
  111.     deleteContact(e, m) {  
  112.         //debugger  
  113.         e.preventDefault();  
  114.         var IsConf = confirm('You are about to delete ' + m.firstName + '. Are you sure?');  
  115.         if (IsConf) {  
  116.             this.contactService.deleteContact(m.contactId).subscribe(response => {  
  117.                 this.resmessage = response;  
  118.                 this.getContacts();  
  119.             });  
  120.         }  
  121.     }  
  122.     reset() {  
  123.         this.editContactId = 0;  
  124.         this._formGroup();  
  125.     }  
  126. }  
Let’s take a closer look at the below code snippet, we have the service method call in here, but the unknown term Subscribe - What is it for? Below we have a simple explanation.
  1. this.contactService.getContacts().subscribe(  
  2. contacts => this.contacts = contacts  
  3. );  
Subscribe: The subscriber function to be passed to the Observable constructor.

Services

In our service file, we have HTTP service [Get, GetByID, Post, Put, Delete] that connects with WebAPI to perform the operations Create, Read, Update & Delete.

GET ALL: Performs a request with `get` http method. For Collection of Object,
  1. //Get  
  2. getContacts(): Observable<ContactModel[]> {  
  3. //debugger  
  4. return this._http.get(this._getUrl)  
  5. .map(res => <ContactModel[]>res.json())  
  6. .catch(this.handleError);  
  7. }  
GET By ID: Performs a request with `get` http method. For Single Object
  1. //GetByID  
  2. getContactByID(id: string): Observable<ContactModel> {  
  3. //debugger  
  4. var getByIdUrl = this._getByIdUrl + '/' + id;  
  5. return this._http.get(getByIdUrl)  
  6. .map(res => <ContactModel>res.json())  
  7. .catch(this.handleError);  
  8. }  
POST: Performs a request with `post` http method.
  1. //Post  
  2. saveContact(contact: ContactModel): Observable<string> {  
  3. //debugger  
  4. let body = JSON.stringify(contact);  
  5. let headers = new Headers({ 'Content-Type''application/json' });  
  6. let options = new RequestOptions({ headers: headers });  
  7.   
  8. //http.post(url: string, body: string, options ?: RequestOptionsArgs): Observable<Response>  
  9. return this._http.post(this._saveUrl, body, options)  
  10. .map(res => res.json().message)  
  11. .catch(this.handleError);  
  12. }  
PUT: Performs a request with `put` http method.
  1. //Put  
  2. updateContact(contact: ContactModel, id: string): Observable < string > {  
  3.     //debugger  
  4.     var updateUrl = this._updateUrl + '/' + id;  
  5.     var body = JSON.stringify(contact);  
  6.     var headers = new Headers();  
  7.     headers.append('Content-Type''application/json');  
  8.     //http.post(url: string, body: string, options ?: RequestOptionsArgs): Observable<Response>  
  9.     return this._http.put(updateUrl, body, {  
  10.         headers: headers  
  11.     }).map(response => response.json().message).catch(this.handleError);  
  12. }  
DELETE: Performs a request with `delete` http method.
  1. //Delete  
  2. deleteContact(id: string): Observable < string >   
  3.   {  
  4.     //debugger  
  5.     var deleteByIdUrl = this._deleteByIdUrl + '/' + id  
  6.         //http.post(url: string, options ?: RequestOptionsArgs): Observable<Response>  
  7.     return this._http.delete(deleteByIdUrl).map(response => response.json().message).catch(this.handleError);  
  8. }  
Observable : [Observable<T>] A representation of any set of values over any amount of time. This the most basic building block of RxJS.

Let’s put it together in Contact.service file.

Contact.service.ts
  1. import {  
  2.     Injectable,  
  3.     Component  
  4. } from 'angular2/core';  
  5. import {  
  6.     Http,  
  7.     Request,  
  8.     RequestMethod,  
  9.     Response,  
  10.     RequestOptions,  
  11.     Headers  
  12. } from 'angular2/http';  
  13. import 'rxjs/Rx';  
  14. import {  
  15.     Observable  
  16. } from 'rxjs/Observable';  
  17. import {  
  18.     ContactModel  
  19. } from './contact.model';  
  20. @Component({  
  21.     providers: [Http]  
  22. })  
  23. @Injectable()  
  24. export class ContactService {  
  25.     public headers: Headers;  
  26.     constructor(private _http: Http) {}  
  27.     public _saveUrl: string = '/api/Contact/PostContact/';  
  28.     public _updateUrl: string = '/api/Contact/PutContact/';  
  29.     public _getUrl: string = '/api/Contact/GetContact/';  
  30.     public _getByIdUrl: string = '/api/Contact/GetContactByID/';  
  31.     public _deleteByIdUrl: string = '/api/Contact/DeleteContactByID/';  
  32.     //Get  
  33.     getContacts(): Observable < ContactModel[] > {  
  34.             //debugger  
  35.             return this._http.get(this._getUrl).map(res => < ContactModel[] > res.json()).catch(this.handleError);  
  36.         }  
  37.         //GetByID  
  38.     getContactByID(id: string): Observable < ContactModel > {  
  39.             //debugger  
  40.             var getByIdUrl = this._getByIdUrl + '/' + id;  
  41.             return this._http.get(getByIdUrl).map(res => < ContactModel > res.json()).catch(this.handleError);  
  42.         }  
  43.         //Post  
  44.     saveContact(contact: ContactModel): Observable < string > {  
  45.             //debugger  
  46.             let body = JSON.stringify(contact);  
  47.             let headers = new Headers({  
  48.                 'Content-Type''application/json'  
  49.             });  
  50.             let options = new RequestOptions({  
  51.                 headers: headers  
  52.             });  
  53.             //http.post(url: string, body: string, options ?: RequestOptionsArgs): Observable<Response>  
  54.             return this._http.post(this._saveUrl, body, options).map(res => res.json().message).catch(this.handleError);  
  55.         }  
  56.         //Put  
  57.     updateContact(contact: ContactModel, id: string): Observable < string > {  
  58.             //debugger  
  59.             var updateUrl = this._updateUrl + '/' + id;  
  60.             var body = JSON.stringify(contact);  
  61.             var headers = new Headers();  
  62.             headers.append('Content-Type''application/json');  
  63.             //http.post(url: string, body: string, options ?: RequestOptionsArgs): Observable<Response>  
  64.             return this._http.put(updateUrl, body, {  
  65.                 headers: headers  
  66.             }).map(response => response.json().message).catch(this.handleError);  
  67.         }  
  68.         //Delete  
  69.     deleteContact(id: string): Observable < string > {  
  70.         //debugger  
  71.         var deleteByIdUrl = this._deleteByIdUrl + '/' + id  
  72.             //http.post(url: string, options ?: RequestOptionsArgs): Observable<Response>  
  73.         return this._http.delete(deleteByIdUrl).map(response => response.json().message).catch(this.handleError);  
  74.     }  
  75.     private handleError(error: Response) {  
  76.         return Observable.throw(error.json().error || 'Opps!! Server error');  
  77.     }  
  78. }  
Let’s discus about form in Angular2, there are two strategis of Angular2 form.
  1. Template-driven
  2. Model-driven

Template-driven

In template-driven forms, directives are added declaratively in the template.

  1. <input id="firstName" type="text"  
  2. class="form-control"  
  3. placeholder="FirstName" [ngFormControl]="firstName" required>  
Noticed that the validator is added declaratively with the input element “required”.

Model-driven

In our sample app, we have used model-driven form that has ngFormModel & ngFormControl. Here, ngFormControl is binded with input element to get the input values through the control.

ngFormModel: binding it to a controller variable “contactForm”,

<form [ngFormModel]="contactForm">

ngFormControl
  1. <input id="firstName" type="text"   
  2. class="form-control"   
  3. placeholder="FirstName" [ngFormControl]="firstName">  
ControlGroup contains several Controls.
  1. //Form Control  
  2. contactForm: ControlGroup;  
  3. firstName: Control;  
  4. email: Control;  
  5. phone: Control;  
An Injected FormBulder uses the builder to create the control group which is passed as key value pairs.

private builder: FormBuilder

  1. //Form Group  
  2. _formGroup() {  
  3.     //Set Initial Values to the Control & Validators  
  4.     this.firstName = new Control('', Validators.required);  
  5.     this.email = new Control('', Validators.compose([Validators.required, customvalidators.emailValidator]));  
  6.     this.phone = new Control('');  
  7.     //Pass the grouped controls as key value pairs  
  8.     this.contactForm = this.builder.group({  
  9.         firstName: this.firstName,  
  10.         email: this.email,  
  11.         phone: this.phone  
  12.     });  
  13. }  
The validations are also checked in our component. Below, we have our Model-driven complete form.

Form
  1. <form [ngFormModel]="contactForm">  
  2.     <div class="form-group" [ngClass]="{ 'has-error' : !firstName.valid }">  
  3.         <label class="control-label" for="firstName">Username</label>  
  4.         <em *ngIf="!firstName.valid">*</em>  
  5.         <input id="firstName" type="text"   
  6. class="form-control"   
  7. placeholder="FirstName" [ngFormControl]="firstName">  
  8.         </div>  
  9.         <div class="form-group" [ngClass]="{ 'has-error' : !email.valid }">  
  10.             <label class="control-label" for="email">Email</label>  
  11.             <em *ngIf="!email.valid">*</em>  
  12.             <input id="email" type="email"   
  13. class="form-control"   
  14. placeholder="Email" [ngFormControl]="email">  
  15.             </div>  
  16.             <div class="form-group">  
  17.                 <label class="control-label" for="phone">Phone</label>  
  18.                 <input id="phone" type="text" class="form-control" placeholder="Phone" [ngFormControl]="phone">  
  19.                 </div>  
  20.                 <div class="form-group">  
  21.                     <button type="submit" class="btn btn-danger" (click)="reset()">Reset</button>  
  22.                     <button type="submit" class="btn btn-primary" (click)="saveContact(contactForm.value)"   
  23. *ngIf="editContactId == 0"   
  24. [disabled]="!contactForm.valid">Create</button>  
  25.                     <button type="submit" class="btn btn-success" (click)="updateContact(contactForm.value)"   
  26. *ngIf="editContactId > 0"   
  27. [disabled]="!contactForm.valid">Update</button>  
  28.                 </div>  
  29.             </form>  
Here is the complete contact View page which we have used in our application.

Contact.view.html
  1. <div class="row">  
  2.     <div class="col-sm-4">  
  3.         <h3>Phone Book {{addmessage}}</h3>  
  4.         <form [ngFormModel]="contactForm">  
  5.             <div class="form-group" [ngClass]="{ 'has-error' : !firstName.valid }">  
  6.                 <label class="control-label" for="firstName">Username</label>  
  7.                 <em *ngIf="!firstName.valid">*</em>  
  8.                 <input id="firstName" type="text"   
  9. class="form-control"   
  10. placeholder="FirstName" [ngFormControl]="firstName">  
  11.                 </div>  
  12.                 <div class="form-group" [ngClass]="{ 'has-error' : !email.valid }">  
  13.                     <label class="control-label" for="email">Email</label>  
  14.                     <em *ngIf="!email.valid">*</em>  
  15.                     <input id="email" type="email"   
  16. class="form-control"   
  17. placeholder="Email" [ngFormControl]="email">  
  18.                     </div>  
  19.                     <div class="form-group">  
  20.                         <label class="control-label" for="phone">Phone</label>  
  21.                         <input id="phone" type="text" class="form-control" placeholder="Phone" [ngFormControl]="phone">  
  22.                         </div>  
  23.                         <div class="form-group">  
  24.                             <button type="submit" class="btn btn-danger" (click)="reset()">Reset</button>  
  25.                             <button type="submit" class="btn btn-primary" (click)="saveContact(contactForm.value)"   
  26. *ngIf="editContactId == 0"   
  27. [disabled]="!contactForm.valid">Create</button>  
  28.                             <button type="submit" class="btn btn-success" (click)="updateContact(contactForm.value)"   
  29. *ngIf="editContactId > 0"   
  30. [disabled]="!contactForm.valid">Update</button>  
  31.                         </div>  
  32.                     </form>  
  33.                     <span class="warning">{{resmessage}}</span>  
  34.                 </div>  
  35.                 <div class="col-sm-8">  
  36.                     <h3>Phone Book {{listmessage}}</h3>  
  37.                     <table style="width:100%" class="table table-striped">  
  38.                         <tr>  
  39.                             <th>ID</th>  
  40.                             <th>Firstname</th>  
  41.                             <th>Email</th>  
  42.                             <th>Phone</th>  
  43.                             <th>Option</th>  
  44.                         </tr>  
  45.                         <tr *ngFor="#contact of contacts">  
  46.                             <td>{{ contact.contactId }}</td>  
  47.                             <td>{{ contact.firstName }}</td>  
  48.                             <td>{{ contact.email }}</td>  
  49.                             <td>{{ contact.phone }}</td>  
  50.                             <td>  
  51.                                 <a href="javascript:void(0)"  
  52. (click)="deleteContact($event, contact)"  
  53. class="btn btn-danger btn-xs pull-right">Delete</a>  
  54.                                 <a href="javascript:void(0)"  
  55. (click)="editContact($event, contact)"  
  56. class="btn btn-primary btn-xs pull-right">Edit</a>  
  57.                             </td>  
  58.                         </tr>  
  59.                     </table>  
  60.                 </div>  
  61.             </div>  
This is all from our Angular section in our sample app that we have used to perform client-end operation. Now, it’s time to build & run the application. Next, we will get overview on Server Configuration.

Configure Server

Outside IIS (Weblistener): We can host & run our application without an IIS environment, we need to add command object that tell the hosting to use the HTTP server weblistener (Windows-only).
  1. "commands": {  
  2. "OutsideIIS""Microsoft.AspNet.Hosting --server Microsoft.AspNet.Server.Weblistener --server.urls http://localhost:5001"  
  3. },  
Make sure the dependencies is exist
"Microsoft.AspNetCore.Server.WebListener": "0.1.0"

Now, go to Solution Explorer, right click project > properties > Debug , change the profile to Outside IIS.

properties

Set launch URL, then save & run the application.

properties

Server will start with hosting environment details,

details

The application is running on the URL http://localhost:5000 with details request info.

details

Inside IIS (Kestrel): Kestrel is a cross-platform web server which is run behind IIS or Nginx.

IIS

Change to IIS Express from navigation bar dropdown list to run the application using IIS. OK. Let’s run our application to see the way how it works.

Output

Here, we can see the application output with welcome message & the data is listed from the server through our MVC6 –WebAPI. Here, we can perform CRUD operation with required validation.

Output
I hope this will help.


Similar Articles