CRUD operation in Angular 4 : Angular 4 + Core 2.0 CRUD operation Part II

Angular-12Angular-4-CRUD-Example-Tutorial

Note – You can find the source code of my sample application here.

This post is the Part II post for Angular 4 + Core 2.0 CRUD operation.

In my previous post(Part I), I explained how to do Database first in .Net Core 2.0 and we created Employee Web API by Database first approach which you can find here.

In this Part II post, we will add different Angular component class to do the CRUD operation using the API we created in this post and will show the details on UI as shown below:

crud29

Let us start.

Set routes for API methods

Our first task is to change the routes in API methods so that it would be easier for us to give the path to Angular component pages(Whole class here), For example:

[Route("~/api/GetAllEmployees")] // Add routes in all the methods
[HttpGet]
public IEnumerable GetEmployees()
{
return _context.Employees;
}

Add Employee Folder

Add Employee folder on the ClientApp folder as shown below:

crud24

Get Employees

Let us first add the code to get all employees and later we will add the code for Add, Update, Delete.

For this we will follow below steps:

  • Add EmployeeService TypeScript file
  • Add Employee HTML file
  • Add Employee component class
  • Add EmployeeComponent in the ApModule
  • Add Employee Management in the Navigation Menu

Add EmployeeService TypeScript file

We will add EmployeeService typescript file under Employee folder.

Add below code in the EmployeeService.ts class:


// Importing the libraries
import { Injectable } from "@angular/core";
import { Http, Response, Headers } from "@angular/http";
import "rxjs/add/operator/map";
import 'rxjs/add/operator/do'; // debug
import { Observable } from "rxjs/Observable";
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
// To inject the dependancies in the service
@Injectable()
export class EmployeeService {
public employeeList: Observable<Employee[]>;
private _employeeList: BehaviorSubject<Employee[]>;
private baseUrl: string;
private dataStore: {
employeeList: Employee[];
};

//// Constructor to set the values
constructor(private http: Http) {
// Base URL for the API
this.baseUrl = '/api/';
this.dataStore = { employeeList: [] };
this._employeeList = <BehaviorSubject<Employee[]>>new BehaviorSubject([]);
this.employeeList = this._employeeList.asObservable();
}

// Method to get all employees by calling /api/GetAllEmployees
getAll() {
this.http.get(`${this.baseUrl}GetAllEmployees`)
.map(response => response.json())
.subscribe(data => {
this.dataStore.employeeList = data;
// Adding newly added Employee in the list
this._employeeList.next(Object.assign({}, this.dataStore).employeeList);
}, error => console.log('Could not load employee.'));
}
}

As you can see in above code, we are getting all the employees by calling /api/GetAllEmployees

Add Employee HTML file

Add below HTML code to the file:

<div id="summary" class="section panel panel-primary">
<div class="panel-heading"> Employee Summary</div>
<div class="container">
<!--{{employeeList | json}}-->
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>City</th>
<th>Country</th>
<th></th>
</tr>
<tr>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
<th></th>
</tr>
</thead>
<tbody *ngFor="let item of employeeList | async">
<tr>
<td><input type="text" [(ngModel)]='item.empName' /></td>
<td><input type="text" [(ngModel)]='item.empAge' /></td>
<td><input type="text" [(ngModel)]='item.empCity' /></td>
<td><input type="text" [(ngModel)]='item.empCountry' /></td>
<td></td>
<td></tr>
</tbody>
</table>
</div>
</div>

Here we have used:

  • ngFor to use for loop into the Employee list
  • Bound the Employee model from the component

Add Employee component class

Add below code in the component class:

import { Component, OnInit } from '@angular/core';
import 'rxjs/add/operator/catch';
import { EmployeeService } from "./employeeService";
import { Observable } from "rxjs/Observable";
import { Employee } from "./employeeService"

//Here we specified the provider as EmployeeService and html path which we will add later

@Component({
selector: 'employee',
providers: [EmployeeService],
templateUrl: './employee.component.html'
})

//After that add below code which will be used to get the data from the service
export class EmployeeComponent implements OnInit {
public employeeList: Observable<Employee[]>;
showEditor = true;
myName: string;
employee: Employee;
constructor(private dataService: EmployeeService) {
this.employee = new Employee();
}
ngOnInit() {
// if you want to debug info just uncomment the console.log lines.
// console.log("You are in ngOnInit");
this.employeeList = this.dataService.employeeList;
this.dataService.getAll();
}}

As you can see in above code, we have specified that application should call GetAll method of the service on init.

Add EmployeeComponent in the ApModule

Add EmployeeComponent to the class app.shared.module.ts as shown below:

import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { FormsModule } from '@angular/forms';
import { HttpModule } from '@angular/http';
import { RouterModule } from '@angular/router';

import { AppComponent } from './components/app/app.component';
import { NavMenuComponent } from './components/navmenu/navmenu.component';
import { HomeComponent } from './components/home/home.component';
import { FetchDataComponent } from './components/fetchdata/fetchdata.component';
import { CounterComponent } from './components/counter/counter.component';
import { EmployeeComponent } from './components/Employee/employee.component'; // Added EmployeeComponent here

@NgModule({
declarations: [
AppComponent,
NavMenuComponent,
CounterComponent,
FetchDataComponent,
HomeComponent,
EmployeeComponent  // Added EmployeeComponent here
],
imports: [
CommonModule,
HttpModule,
FormsModule,
RouterModule.forRoot([
{ path: '', redirectTo: 'home', pathMatch: 'full' },
{ path: 'employee', component: EmployeeComponent }, // Added EmployeeComponent here
{ path: 'home', component: HomeComponent },
{ path: 'counter', component: CounterComponent },
{ path: 'fetch-data', component: FetchDataComponent },
{ path: '**', redirectTo: 'home' }
])
]
})
export class AppModuleShared {
}

Add Employee Management in the Navigation Menu

Update Navigation menu and add the Employee link as below:

<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']">NeelAngular4CRUD</a></div>
<div class='clearfix'></div>
<div class='navbar-collapse collapse'>
<ul class='nav navbar-nav'>
	<li [routerLinkActive]="['link-active']">
<a [routerLink]="['/employee']">
<span class='glyphicon glyphicon-employee'></span> Employee Management
</a></li>
	<li [routerLinkActive]="['link-active']">
<a [routerLink]="['/home']">
<span class='glyphicon glyphicon-home'></span> Home
</a></li>
	<li [routerLinkActive]="['link-active']">
<a [routerLink]="['/counter']">
<span class='glyphicon glyphicon-education'></span> Counter
</a></li>
	<li [routerLinkActive]="['link-active']">
<a [routerLink]="['/fetch-data']">
<span class='glyphicon glyphicon-th-list'></span> Fetch data
</a></li>
</ul>
</div>
</div>
</div>

Let us test our changes

Run the application and click on Employee Management: crud25 As you can see all the data, which are there in the database, are displayed here.

Add, Update and Delete Employees

As we can see the list of Employees, it is time to add and update them. First of all, we will update the HTML and will add below lines:

<button class="btn btn-xs btn-primary">Update</button>

<button class="btn btn-xs btn-primary">Remove</button>

as shown below:

crud26

Changes in Employee Service for Add, Update, Delete

For adding:

public addEmployee(employee: Employee) {
console.log("add Employee");
var headers = new Headers();
headers.append('Content-Type', 'application/json; charset=utf-8');
console.log('add Employee : ' + JSON.stringify(employee));

this.http.post(`${this.baseUrl}AddEmployee/`, JSON.stringify(employee), { headers: headers })
.map(response => response.json()).subscribe(data => {
this.dataStore.employeeList.push(data);
this._employeeList.next(Object.assign({}, this.dataStore).employeeList);
}, error => console.log('Could not create todo.'));
};

For Updating:

public updateEmployee(newEmployee: Employee) {
console.log("update Employee");
var headers = new Headers();
headers.append('Content-Type', 'application/json; charset=utf-8');
console.log('Update Employee : ' + JSON.stringify(newEmployee));

this.http.put(`${this.baseUrl}UpdateEmployee/`, JSON.stringify(newEmployee), { headers: headers })
.map(response => response.json()).subscribe(data => {
alert("hi");
this.dataStore.employeeList.forEach((t, i) => {
if (t.studentId === data.id) { this.dataStore.employeeList[i] = data; }
});
}, error => console.log('Could not update todo.'));
};

For Deleting:

removeItem(employeeId: number) {
var headers = new Headers();
headers.append('Content-Type', 'application/json; charset=utf-8');
console.log("removeItem:" + employeeId);
this.http.delete(`${this.baseUrl}DeleteEmployee/${employeeId}`, { headers: headers }).subscribe(response => {
this.dataStore.employeeList.forEach((t, i) => {
if (t.studentId === employeeId) { this.dataStore.employeeList.splice(i, 1); }
});

this._employeeList.next(Object.assign({}, this.dataStore).employeeList);
}, error => console.log('Could not delete Employee.'));
}

Changes in Employee Component for Add, Update, Delete

For Adding:

public addEmployee(item: Employee) {
let todoId = this.dataService.addEmployee(this.employee);
}

For Updating:

public updateEmployee(item: Employee) {
this.dataService.updateEmployee(item);
}

For Deleting:

public deleteEmployee(employeeId: number) {
this.dataService.removeItem(employeeId);
}

This is it!

Let us first test Add methods:

Add the details as shown below and click on Add:

crud27

The value will be added at the end and also will be added to the database once you click on Add:

crud28

Same with Update, once you update something Inline and click on Update, the row would be updated along with the Database:

crud29

The database would also be reflected as shown below:

crud29

And to remove, just click on Remove button of the row which you want to delete:

crud29

The row would be removed from UI and the database would also get reflected:

crud29

Note – You can find the source code of my sample application here.

Hope it helps.

Advertisements

Database first in .Net Core 2.0 step by step: Angular 4 + Core 2.0 CRUD operation Part I

Untitled design (1)

Note Part II(CRUD operation with Angular 4) of this post is here.

In my previous post, I have explained how to create an Angular 5 application in Visual Studio 2017 using .Net Core templates which you can find here.

In this series of posts, I will explain the Create, Read, Update, Delete(CRUD) using Angular 5 with .Net Core 2 API.

In this part I post, we will see how to do Database first set up in Angular(.Net Core 2.0 project) and will set up the Employee API.

prerequisite:

  • Visual studio 2017 community edition, download here
  • .Net Core 2.0 SDK from here (I have written a post to install SDK here)

Create the Angular application using .Net Core 2.0 template in VS 2017

Once you have all these installed, open your Visual Studio 2017 -> Create New Project -> Select Core Web application:

az1

Click on Ok and in next window, select Angular as shown below:

az2

Visual Studio will create a well-structured application for you(Note that I have manually added Models folder as we will require this in future):

crud3

I will not go deep into the Angular structure in this post but if you require more details then I have written a detailed post on Angular and .Net Core 2.0 which you find here.

Once you run the application on IISExpress, it will have the landing page as below:

crud1

Creation of Employee Database

Let us Create Employee database in SQL, you can use below queries to create the database and table:

CREATE DATABASE AngularCRUDTest;

CREATE TABLE Employees
(
 StudentId [bigint] IDENTITY(1,1) NOT NULL,
 EmpName varchar(50),
 EmpAge int,
 EmpCity varchar(50),
 EmpCountry varchar(50),
 CONSTRAINT [PK_Student] PRIMARY KEY CLUSTERED 
(
 [StudentId] ASC
)
);

INSERT INTO Employees
(EmpName, EmpAge, EmpCity, EmpCountry)
VALUES
('Neel', 27, 'Pune', 'India');

INSERT INTO Employees
(EmpName, EmpAge, EmpCity, EmpCountry)
VALUES
('Neel2', 27, 'Pune', 'India');

INSERT INTO Employees
(EmpName, EmpAge, EmpCity, EmpCountry)
VALUES
('Neel3', 27, 'Pune', 'India');

Once the database is created successfully. it will look as below:

crud2

Add EntityFramework references

Once the database is created, let us add EntityFrameworkCore.SqlServer(Microsoft SQL Server database provider for Entity Framework Core), this will help us to go further with EntityFramework operations.

Search with “Microsoft.EntityFrameworkCore.SqlServer” in Nuget Package Manager and click on Install:

crud4

As we are going to use Database First development approach, we need to install the additional packages below as well:

  • Microsoft.EntityFrameworkCore.Tools(Includes Scaffold-DbContext, Add-Migration, and Update-Database)

crud5

  • Microsoft.EntityFrameworkCore.SqlServer.Design(Design-time Entity Framework Core Functionality for Microsoft SQL Server)

crud6

Entity Model creation

Once we have installed all required references, let us add required context and model classes from existing databases.

.Net Team has made this step easier and now we just need to run below line in Package Manager Console:

Scaffold-DbContext “Server=.\SQL2012;Database=AngularCRUDTest;Trusted_Connection=True;” Microsoft.EntityFrameworkCore.SqlServer -OutputDir Models

Here use the connection string as per your database and the –OutputDir attribute allows you to specify the location of the files generated. In this case, we’ve set it to Models(folder which we have added previously).

crud7

Once you run above code, it will create the Context class and Employee class into the Models folder as shown below:

crud8.png

AngularCRUDTestContext.cs class(https://github.com/NeelBhatt/Angular4_2_5CRUD/blob/master/NeelAngular4CRUD/Models/AngularCRUDTestContext.cs):

crud9

Employees.cs class represents the Employees table(https://github.com/NeelBhatt/Angular4_2_5CRUD/blob/master/NeelAngular4CRUD/Models/Employees.cs):

crud10

Once this is done, we will add the connection string into appsettings.json file, in .Net core we have json file instead of web.config files(https://github.com/NeelBhatt/Angular4_2_5CRUD/blob/master/NeelAngular4CRUD/appsettings.json):

crud11.png

Next step is to add DB Context to the Startup.cs class.

Add below references into the Startup.cs class:

using NeelAngular5CRUD.Models;
using Microsoft.EntityFrameworkCore;

Add below lines into the ConfigureService method:

services.AddDbContext(options => options.UseSqlServer(Configuration.GetConnectionString("AngularCRUDTestDatabase")));

Statup.cs class looks like below(https://github.com/NeelBhatt/Angular4_2_5CRUD/blob/master/NeelAngular4CRUD/Startup.cs):

crud12

As shown in above code, we are passing configuration to AddDbContext so we are required to add a constructor in AngularCRUDTestContext that accepts DbContextOptions.

For that go to AngularCRUDTestContext class and remove OnConfiguring method as we do not need it and add the constructor to allow the configuration to be passed into the context by dependency injection:

public AngularCRUDTestContext(DbContextOptions options)
 : base(options)
 { }

After making the changes, AngularCRUDTestContext  class looks as below(https://github.com/NeelBhatt/Angular4_2_5CRUD/blob/master/NeelAngular4CRUD/Models/AngularCRUDTestContext.cs):

crud9

If we do not add above constructor then after running we will get below exception:

crud17.png

That is it. We have completed all required code.

Add API controller with actions using Entity Framework

Right click on Controllers folder -> Add new Controller -> select API controller with actions using Entity Framework:

crud14

In next window, select Employees in Model drop-down and AngularCRUDTestContext in Data context drop-down:

crud15

Once you click on Add, an EmployeeController API class will be created with all the CRUD operations as shown below:

crud16

Let us test our API, run the application:

http://localhost:53008/api/Employees

crud18

As you can see all the employees which we added to the database are returned which shows our code is working fine.

In my next post, we will add different Angular component class to do the CRUD operation using the API we created in this post and will show the details on UI.

Note Part II(CRUD operation with Angular 4) of this post is here.

Hope it helps.

 

Image detection bot using Microsoft Vision API : Step by step guide

bot9

Note – You can find the source code of my sample application here.

In my previous post about Bots, I have explained how to use FormFlow to create attractive selection box in bots which you can find here.

In this post, I will explain how to create Image detection bot using Microsoft Vision API.

Let us see how to create Image detection Bot application using Visual Studio 2017.

prerequisite:

Also if you want to have Bot Application as a template then as a workaround just download this  (download would start once you click on the link) project and put the extracted folder into below location:

C:\Users\YourName\Documents\Visual Studio 2015\Templates\ProjectTemplates\Visual C#

Once this is done, you can see Bot Application template as shown below:

bot1

Click on Bot Application and then it will create a sample project which has the structure as below:

bot2

Here MessagesController is created by default and it is the main entry point of the application.

I have written the post to setup basic Bot application which you can find here. So if you get errors then I would suggest you to first take a look at above link.

Now replace the code of MessagesController with below code:

 using System;
 using System.IO;
 using System.Linq;
 using System.Net;
 using System.Net.Http;
 using System.Text.RegularExpressions;
 using System.Threading.Tasks;
 using System.Web.Http;
 using NeelImageDetectionBot.Service;
 using Microsoft.Bot.Builder.Dialogs;
 using Microsoft.Bot.Connector;

namespace NeelImageDetectionBot
 {
 [BotAuthentication]
 public class MessagesController : ApiController
 {
 private readonly IImageService captionService = new ImageService();

 ///
 /// POST: api/Messages
 /// Receive a message from a user and reply to it
 /// 
 public async Task Post([FromBody]Activity activity)
 {
   if (activity.Type == ActivityTypes.Message)
   {
    //await Conversation.SendAsync(activity, () => new Dialogs.RootDialog());
    var connector = new ConnectorClient(new Uri(activity.ServiceUrl));
    string message;
    try
    {
      message = await this.GetCaptionAsync(activity, connector);
    }
    catch (Exception ex)
    {
      message = "Welcome to Image detection Bot , Please Upload or share Image Url ";
    }

 Activity reply = activity.CreateReply(message);
 await connector.Conversations.ReplyToActivityAsync(reply);
  }
  else
  {
     HandleSystemMessage(activity);
  }
  var response = Request.CreateResponse(HttpStatusCode.OK);
  return response;
 }

private Activity HandleSystemMessage(Activity message)
 {
  if (message.Type == ActivityTypes.DeleteUserData)
  {
    // Implement user deletion here
    // If we handle user deletion, return a real message
  }
  else if (message.Type == ActivityTypes.ConversationUpdate)
  {
   // Handle conversation state changes, like members being added and removed
   // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info
   // Not available in all channels
  }
  else if (message.Type == ActivityTypes.ContactRelationUpdate)
  {
   // Handle add/remove from contact lists
   // Activity.From + Activity.Action represent what happened
  }
  else if (message.Type == ActivityTypes.Typing)
  {
   // Handle knowing tha the user is typing
  }
  else if (message.Type == ActivityTypes.Ping)
  {
  }

  return null;
 }

private async Task GetCaptionAsync(Activity activity, ConnectorClient connector)
 {
   var imageAttachment = activity.Attachments?.FirstOrDefault(a => a.ContentType.Contains("image"));
   if (imageAttachment != null)
   {
    using (var stream = await GetImageStream(connector, imageAttachment))
   {
     return await this.captionService.GetCaptionAsync(stream);
   }
 }

  string url;
 if (TryParseAnchorTag(activity.Text, out url))
 {
   return await this.captionService.GetCaptionAsync(url);
 }

 if (Uri.IsWellFormedUriString(activity.Text, UriKind.Absolute))
 {
   return await this.captionService.GetCaptionAsync(activity.Text);
 }

 // If we reach here then the activity is neither an image attachment nor an image URL.
 throw new ArgumentException("The activity doesn't contain a valid image attachment or an image URL.");
 }

 private static async Task GetImageStream(ConnectorClient connector, Attachment imageAttachment)
 {
   using (var httpClient = new HttpClient())
   {
     var uri = new Uri(imageAttachment.ContentUrl);
     return await httpClient.GetStreamAsync(uri);
   }
 }

 /// <summary> 
 /// Gets the href value in an anchor element. 
 /// </summary> 
 private static bool TryParseAnchorTag(string text, out string url)
 {
   var regex = new Regex("^[^\"]*)\">[^<]*$", RegexOptions.IgnoreCase);
   url = regex.Matches(text).OfType().Select(m => m.Groups["href"].Value).FirstOrDefault();
   return url != null;
   }
  }
 }

Here we have written all necessary code:

  • To get the Image if URL is provided
  • How code should behave when the user posts something
  • Getting Image caption by calling Vision API methods in ImageService class

As you can see we have given the reference of IImageService and ImageService in above code.

Let us first add IImageService interface and add below code to the interface:

using System.IO;
using System.Threading.Tasks;

namespace NeelImageDetectionBot.Service
{
 internal interface IImageService
 { 
  /// Gets the caption of an image stream. 
  Task GetCaptionAsync(Stream stream);

  /// Gets the caption of an image URL. 
  Task GetCaptionAsync(string url);
 }
}

Here we have written the method signatures(for getting caption of image) which we will add in ImageService class which will be inherited from IImageService interface.

Let us add ImageService class and add below code:

using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.ProjectOxford.Vision;
using Microsoft.ProjectOxford.Vision.Contract;

namespace NeelImageDetectionBot.Service
{
  public class ImageService : IImageService
  {
   /// Microsoft Computer Vision API key.
   private static readonly string ApiKey = "VisionApiKey"; //// Need to add Vision API Key here
 
   /// The set of visual features we want from the Vision API. 
   private static readonly VisualFeature[] VisualFeatures = { VisualFeature.Description };

   public async Task<string> GetCaptionAsync(string url)
   {
     var client = new VisionServiceClient(ApiKey);
     var result = await client.AnalyzeImageAsync(url, VisualFeatures);
     return ProcessAnalysisResult(result);
   }

   public async Task<string> GetCaptionAsync(Stream stream)
   {
     var client = new VisionServiceClient(ApiKey);
     var result = await client.AnalyzeImageAsync(stream, VisualFeatures);
     return ProcessAnalysisResult(result);
   }

  /// Processes the analysis result.
  private static string ProcessAnalysisResult(AnalysisResult result)
  {
     string message = result?.Description?.Captions.FirstOrDefault()?.Text;
     return string.IsNullOrEmpty(message) ?
       "Couldn't find a caption for this one" :
       "As per my analysis it's " + message;
 }

 

After adding this, you will get errors because the application cannot find reference Microsoft.ProjectOxford.Vision.

Let us add the reference from Nuget as shown below:

bot3

ImageRecognition class has an important method named AnalizeImage which basically reads the image from the location and transfers it into the stream. Then it calls below API method and passes the image stream:

client.AnalyzeImageAsync(stream, visualFeatures);

Above method will return AnalysisResult which can be extracted as below:

string message = result?.Description?.Captions.FirstOrDefault()?.Text;

So basically Image caption is the text it will return after analyzing the image.

Vision API Key

Concentrate on below line in above code:

private static readonly string ApiKey = "VisionApiKey";

Note that you will be required to add an API key which you can get from the Cognitive Service page of Azure here.

Click on Vision as shown below:

bot4.png

Click on Computer Vision API as shown below:

bot5

Click on Get API Key:

bot6

Note that API Key and put it in the code as shown in above code. For security reason, I have kept the key empty.

Our Bot is ready now, just click on start button and you will see below window:

bot9

As I explained in my previous post, we will require a Bot Emulator to test our bot.

So we will start testing our bot by providing our bot URL which is http://localhost:3979/api/messages

Let us test our Bot:

If we want to test our bots locally then Bot emulator is the best option.

The Bot Framework Emulator is a desktop application that allows bot developers to test and debug their bots on localhost or running remotely through a tunnel.

As we mentioned on top of the post, you can download the Bot emulator from here. Or you can click below, it will start the download automatically:

botframework-emulator-Setup-3.5.33.exe

Click on exe, it will start the installation:

bot10

And once the installation is done, it will have a landing page as below, here you need to give the URL of your bot application(http://localhost:3979/api/messages):

bot13

It will ask you for Microsoft App Id and password, but for now, do not give anything there and click on CONNECT.

Now your bot is ready to be tested.

Upload any random images and the bot will respond:

bot7

Some more images:

bot9

As you can see the image is detected and Vision API returned the result as per the analysis.

Note – You can find the source code of my sample application here.

Hope it helps.

Create Angular 5 application using .Net Core 2.0 Template in Visual Studio 2017

Untitled design

Angular 5 has been announced recently and we already have a template added in the Visual Studio 2017 with .Net Core 2.0

If you want to know more about Angular in .Net Core then my post may help you to get the basic which you can find here and if you want to see how can we deploy the Angular applications on Azure then have a look at my post here.

In this post, we will see how to add Angular 5 template in your Visual Studio and create an Angular 5 application using .Net Core 2.0 templates.

Prerequisite:

  • Visual studio 2017 community edition, download here
  • .Net Core 2.0 SDK from here (I have written a post to install SDK here)
  • Node.js Version 9 or above from here

Add Angular 5 template

Once you have all these installed, open your Visual Studio 2017 -> Create New Project -> Go to Online tab and search with Angular5:

ang1

Select the Angular5TemplateCore and click on Ok.

Downloading of the template will be started once you click on Ok:

ang2

Once the download gets completed, an installer will be opened which will install the template in Visual Studio 2017.

Note – Close all running instances of the Visual Studio to have a smooth installation of the template.

The wizard will ask you to click on Modify:

ang3

Once you click on Modify, the installation will be completed:

ang4

Create Angular 5 application

Once you have the template installed, open your Visual Studio 2017 -> Create New Project -> Select Installed tab and search with Angular5, now we would be able to see Angular5TF template:

ang5

Click on OK, Visual Studio will create a well-structured Angular 5 application for you:

ang6

Now let us make sure that the application is Angular 5 application.

For that open package.json, here you will be able to see angular version 5.0.0 and Angular CLI version 1.5:

ang7

Next step is to install WebPack.

What is WebPack?

WebPack is a module bundler.

WebPack is used to determine the dependencies, run transformations and create bundles that you can provide to your browser.

ang8

It is a good practice to add WebPack to the starting point that is why we will add below lines in package.json file if it is not there already:

postinstall“: “webpack –config webpack.config.vendor.js”

ang9

You may get below error if you have not added WebPack details in the package.json file:

Cannot find module ‘./wwwroot/dist/vendor-manifest.json’ 

To avoid this error, we need to run above WebPack command first. That is why we have added the command to the package.json file.

After adding above line, build the project. First time when you build the solution, it would take several minutes as it installs some dependencies.

Run the Angular application

Now click on IISExpress to run the application.

After 5-10 seconds, the application might have compilation error as below in Vendor.js file:

An exception has been encountered. This may be caused by an extension.

You can get more information by examining the file ‘C:\Users\neel\AppData\Roaming\Microsoft\VisualStudio\15.0_b495e641\ActivityLog.xml’.

ang10

This error comes because IE does not support several functions used in the project. You need to import some libraries to resolve this error. Have a look here to resolve the error.

Once the error is resolved, the application will run properly:

ang11

Hope it helps.

 

 

 

Build Angular App with .Net Core 2.0 Template(VS 2017) + deploy on Azure: Step by step guide

az13

Note – You can find the source code of my sample application here.

In my previous article, I have explained how to use .Net Core 2.0 Identity in your .Net Core 2.0 application, you can find the article here.

In this article, we will see how to create your Angular application using Visual Studio 2017(.Net Core 2.) and will deploy it to Azure.

prerequisite:

  • Visual studio 2017 community edition, download here
  • Azure account, you can create free trial account here
  • .Net Core 2.0 SDK from here (I have written a post to install SDK here)

Create the Angular application using .Net Core 2.0 template in VS 2017

Once you have all these installed, open your Visual Studio 2017 -> Create New Project -> Select Core Web application:

az1

Click on Ok and in next window, select Angular as shown below:

az2

Visual Studio will create a well-structured application for you:

az3

I will not go deep into the Angular structure in this post but if you require more details then I have written a detailed post on Angular and .Net Core 2.0 which you find here.

Once you run the application on IISExpress, it will have the landing page as below:

az4

Till now we have successfully created an Angular application using Visual Studio 2017 template and ran it on IISExpress.

Publish the Angular application on Azure

Right click on the solution and select Publish:

az5

It will open the window in which you can publish your application on different hosts. Select Microsoft Azure App Service and click on Publish:

az6

Once you click on Publish, it will try to sign you into your Azure account and Visual Studio will fetch the details (like your subscription, Resource Group etc) from your Azure account and will show it on the form. If you are not signed in automatically, you need to sign in manually.

Currently, it is trying to fetch the details from my Azure account:

az7

Resource Group and App Service Plan:

Resource Group is a container in which Azure resources like web apps, databases, and storage accounts are deployed and managed.

App Service Plan is used to specify the size, location etc of your web farm which will host your application.

Click on New and add Resource Group and App Service Plan if you do not have it already.

If you want to add Database then click on Service tab and add\manage the databases:

az8

If you do not wish to add the database then simply click on Create, it publishes the Angular web app to Azure and then launches the app into the default browser:

az9

Note – If you observe the URL then you would understand that the web app name specified in the publish wizard is used as the URL prefix in the format.

for example – http://<app_name>.azurewebsites.net

You have successfully hosted your Angular application on Azure.

RePublish\ReDeploy the recent changes

Let us make some changes on the page and publish our changes to see if the changes are getting reflected in the Azure cloud or not:

I will change the home.component.html page and will modify the texts as below :

az10

Save the changes and right click on the solution and click on Publish again.

Once the process is done, the browser will be launched:

az11

As you can see, our changes are reflected in the Azure cloud.

Now whenever you want to push your recent changes, click on Publish and the Cloud will be updated.

You can manage your web application in the Azure under App services:

az12

Note – You can find the source code of my sample application here.

Hope it helps.

 

 

Authentication in .Net Core 2.0 : .Net Core 2.0 Identity step by step

idn20

Note – You can find the source code of my sample application here.

Whenever you start creating an application, one of the most important modules is the authentication.

In this article, I will explain how to add Login functionality to your .Net Core 2.0 application using .Net Core Identity,

Let us first see what is ASP .Net Core Identity?

ASP.NET Core Identity is a membership system which allows you to add login functionality to your application. Users can create an account and login with a user name and password or they can use an external login provider such as Facebook, Google, Microsoft Account, Twitter or others.

Let us create .Net Core 2.0 application with Core Identity step by step

First open Visual Studio 2017 -> Create New Project -> Select Core Web application

idn1

In next window, click on Change authentication link and select Individual User Accounts. By this, we are selecting the FormAuthentication.

idn2

Then select Web Application(MVC):

idn3

Visual Studio will create a well-structured application for you:

idn4

Let us see some major classes in the application

Controllers

HomeController – For Home, About, Contact pages

AccountController – For Login, Register, ForgotPassword etc with

ManageController – For Change Password, manage profile, to add two-factor authentication etc

Data

ApplicationDBContext along with different migration scripts to create different tables in the database

Extensions

Helper extension class for Email confirmation Link, Reset password callback etc

Models

Different view models for:

  • Account(Login, Register etc)
  • Manage(ChangePassword, EnableAuthentication etc)
  • ApplicationUser
  • ErrorViewModel

Services

For example Email Send service

Views

Views for Account, Manage, Home, About, Contact etc

application.json

This is something new in .Net Core than regular MVC application. Instead of config class now we have json class.

Here the connection string for the aspnet user table resides:

idn5

bundleconfig.json

This is also something different than regular MVC class. This class is used for bundling and minification.

Now open Startup.cs class and add below configuration code in the ConfigureService method.

The services.AddIdentity method adds the default identity system configuration for specific user and role and we will add configuration settings for different Identity options:

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
   services.AddDbContext<ApplicationDbContext>(options =>
   options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

   services.AddIdentity<ApplicationUser, IdentityRole>()
   .AddEntityFrameworkStores<ApplicationDbContext>()
   .AddDefaultTokenProviders();

   services.Configure<IdentityOptions>(options =>
   {
     // Password settings
     options.Password.RequireDigit = true;
     options.Password.RequiredLength = 8;
     options.Password.RequireNonAlphanumeric = false;
     options.Password.RequireUppercase = true;
     options.Password.RequireLowercase = false;
     options.Password.RequiredUniqueChars = 6;

     // Lockout settings
     options.Lockout.DefaultLockoutTimeSpan = TimeSpan.FromMinutes(30);
     options.Lockout.MaxFailedAccessAttempts = 10;
     options.Lockout.AllowedForNewUsers = true;

     // User settings
     options.User.RequireUniqueEmail = true;
     });

    services.ConfigureApplicationCookie(options =>
    {
       // Cookie settings
      options.Cookie.HttpOnly = true;
      options.Cookie.Expiration = TimeSpan.FromDays(150);
      options.LoginPath = "/Account/Login"; // If the LoginPath is not set here, ASP.NET Core will default to /Account/Login
      options.LogoutPath = "/Account/Logout"; // If the LogoutPath is not set here, ASP.NET Core will default to /Account/Logout
      options.AccessDeniedPath = "/Account/AccessDenied"; // If the AccessDeniedPath is not set here, ASP.NET Core will default to /Account/AccessDenied
      options.SlidingExpiration = true;
    });

    // Add application services.
    services.AddTransient<IEmailSender, EmailSender>();

    services.AddMvc();
}

Here we have written the code to add some basic password rules like it should be more than 8 characters, it required digit, it requires at least one Uppercase character etc.

Once this is done, we will enable the Identity in the application by calling UseAuthentication in Configure method as shown below:

idn6

Once this is done, open appsetting.json class and change the ConnectionString and apply your server\DB instance name as below:

idn9

We can test our Identity changes now. Run the application on IISExpress and click on Register.

If you will not provide the password as per our configuration, it will show the message as below:

idn7

Enter the correct password and click on Register.

If this is the first time you’re performing this action, you may be required to run migrations. The application prompts you to Apply Migrations:

idn8

Click on Apply Migrations and give the details again.

Once you click on Register link, the Register action is invoked on AccountController. The Register action creates the user by calling CreateAsync on the _userManager object which is provided to AccountController by dependency injection:

idn10

Once the user is registered, you can open SQL Database and you can see the database would be created for our application:

idn11

You can find registered users under AspNetUsers table.

Similarly, Login method will be called when user logins and it will internally call PasswordSignInAsync on the _signInManager object which is provided to AccountController by dependency injection:

idn14

Once the user is registered\LoggedIn, user claim cookie named AspNetCore.Identity.Application would be created as shown below:

idn12

The Logout method will be called when the user logs out and it will internally call the _signInManager.SignOutAsync method:

idn15

The SignOutAsync method clears the user’s claims stored in a cookie. As you can see below, the cookie is wiped out when the user logs out:

idn13

Two Factor Authentication

You can even add two-factor authentication.

For example in sample application when you click on the User Name, it will open Manage page, click on Two-factor authentication:

idn19

When you click on Add Authenticator app, EnableAuthenticator(Get) will be called which will internally call GenerateQrCodeUri:

idn18

GenerateQrCodeUri will generate the code which then can be added in the Authenticator application as mentioned below:

idn16

Basically, when the user downloads the application and applies this key, the application will generate verification code which needs to be filled here.

When you click on Verify button, it will call EnableAuthenticator method in ManageController which will internally call VerifyTwoFactorTokenAsync, which will verify the toke against the token which is stored against your username when you downloaded the authenticator application:

idn17

Once, the token is verified, the user can use token generated in the application, thus tow factor authentication.

We can add different other two-factor authentication as well. For example for SMS based, have a look here.

Important – In my next post, I will explain IdentityServer4 to secure .Net Core 2.0 API using OAuth 2 client credentials.

Note – You can find the source code of my sample application here.

Hope it helps.

 

 

 

 

 

 

Enable Swagger in your .Net core 2.0 application: Step by step guide

swa13

Note – You can find the source code of my sample application here.

If you have ever worked with APIs then you might be familiar with Swagger, if you have not heard about Swagger then this post will help you to know the basic of Swagger and the steps to configure Swagger with yours .Net Core 2.0 application.

First of all, let us see what is Swagger

One liner for Swagger – UI representation of your RESTfull APIs

  • Swagger is a set of rules (in other words, a specification) for a format describing REST APIs.
  • The format is both machine-readable and human-readable.
  • As a result, it can be used to share documentation among product managers, testers and developers, but can also be used by various tools to automate API-related processes.

For example, you have set of APIs and you want a proper documentation for these APIs, you can use Swagger. You can even test the API calls from Swagger and there is lot more can be done using Swagger, have a look here for more details.

In this post, we will see how can we use Swagger with .Net Core 2.0 application.

Step by step guide:

Open Visual Studio 2017 and Create New project – > Select Core Web application:

swa1

Click on OK, it will open new template window with different awesome templates. Select Web API:

swa2

It will create the API project with the structure shown below:

swa3

Let us add Swagger to the middleware. Open Startup.cs class and add below code to the ConfigureService method:

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc();

services.AddSwaggerGen(c =>
{
 c.SwaggerDoc("v1", new Info
 {
  Version = "v1",
  Title = "My First API",
  Description = "My First ASP.NET Core 2.0 Web API",
  TermsOfService = "None",
  Contact = new Contact() { Name = "Neel Bhatt", Email = "neel.bhatt40@gmail.com", Url = "https://neelbhatt40.wordpress.com/"}
  });
 });
}

Once you add above code, an error will be shown because IServiceCollection does not contain the definition for AddSwaggerGen:

swa4

We will have to add Nuget package – Swashbuckle.AspNetCore to add this support which is used to add Swagger tools for documenting APIs built on ASP.NET Core.

Search Swashbuckle.AspNetCore in Nuget package manager and select the package as shown below:

swa5

Once you install the Nuget package, errors will be gone.

Once this is done, we will enable Swagger UI. Add below code in Configure method of Startup.cs class:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
 if (env.IsDevelopment())
 {
   app.UseDeveloperExceptionPage();
 }

 app.UseMvc();

 app.UseSwagger();
 app.UseSwaggerUI(c =>
 {
   c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
 });
}

We are almost done and we have already enabled Swagger in the Core 2.0 application.

Last but not the least step, we will change the launch browser setting of the application and will tell the application to launch the Swagger when we run the application.

For these Open properties of the application -> Go to Debug tab -> Write swagger in the Launch browser text box:

swa6

That is it. Just run the application and you will see beautiful colorful Swagger landing page as shown below:

swa7

Manage versions of APIs

You can even manage different versions of your APIs, for example, you have v2 APIs as well and you need to enable that in Swagger then you just need to add a couple of steps.

First add new SwaggerDoc in ConfigureService method and then add new endpoint in Configure method in Startup.cs class as shown below:

swa8

Now just run the application and you can select different versions of your APIs by selecting the value from dropdown list as shown below:

swa9

XML documentation

We all are quite familiar with the XML document of the API, for example, you have hosted your APIs and you want to send the details of APIs to another team then you can simply pass XML document which contains all the details of the API like description, desired input, output etc.

Let us see how we can create XML documents with Swagger in .Net Core 2.0 application:

First of all, we need to enable XML support and once we enable the checkbox, the application will create an XML file in the bin\debug folder.

Open properties – > Open Build tab -> Enable check box XML documentation file as below:

swa10

Once this is done, we need to add below lines of code in the ConfigureService method which will include the comments into the XML file:

var basePath = PlatformServices.Default.Application.ApplicationBasePath;
var xmlPath = Path.Combine(basePath, "NeelSwaggerSampleApplication.xml");
c.IncludeXmlComments(xmlPath);

Now add some comments on any random method as shown below:

swa11

And when you build the solution, XML file would be generated in bin\debug folder. Open the XML file, it will show these comments:

swa12

Have a look at the Github page of Swagger UI if you want more information.

You can find the source code of my sample application here.

Hope it helps.

 

 

 

Create your first bot using FormFlow of Bot framework: Demo Movie Booking Bot

flow9

In my last post, I explained how to create your first bot using Visual Studio 2017 which you can find here.

In this post, we will see how to add selection box(forms) to your bot using Microsoft FormFlow.

As explained in my previous post, you can follow the steps to add Bot application into your Visual Studio.

NOTE – the Whole code is available here.

I will use the same solution I created last time and will add one more class which I will name as MovieBooking.

flow1

In this class, we will add different enum, which will work as a select box. It is a real beauty of Bot framework.

For example, let us create the enum for MovieTheatreLocation:

[Serializable]
public enum MovieTheatreLocation
{
  Pune = 1, Bangalore = 2, Mumbai = 3
}

and when we run this on Bot Emulator, it will look like below:

flow2

Let us add all required code to MovieBooking.cs class:

using Microsoft.Bot.Builder.Dialogs; 
using Microsoft.Bot.Builder.FormFlow; 
using System; 

namespace NeelBotDemo.FormFlow
{ 
 [Serializable] 
 public class MovieBooking 
 { 
 public MovieTheatreLocation movieTheatreLocation; 
 public MovieTheatre movieTheatre; 
 public MovieTypes movieTypes; 
 public ClassTypes classTypes; 
 [Optional] 
 public DoYouNeedAMeal doYouNeedAMeal; 
 public FoodMenu foodMenu; 
 public DateTime? DateOfJurney; 
 [Numeric(1, 5)] 
 public int? NumberOfAdult; 
 public int? NumberOfChild; 

 public static IForm<MovieBooking> BuildForm() 
 { 
 return new FormBuilder<MovieBooking>() 
 .Message("Welcome to the Movie Booking BOT created by Neel.") 
 .OnCompletion(async (context, profileForm) => 
 { 
 var userName = string.Empty; 
 context.UserData.TryGetValue<string>("Name", out userName); 
 // Tell the user that the form is complete 
 await context.PostAsync("Thanks for the confirmation " + userName + ". Your booking is successfull"); 
 }) 
 .Build(); 
 } 
} 

 [Serializable]
 public enum MovieTheatreLocation
 {
 Pune = 1, Bangalore = 2, Mumbai = 3
 }
 [Serializable]
 public enum MovieTheatre
 {
 PVR = 1, INOX = 2, CinePolis = 3
 }
 [Serializable]
 public enum MovieTypes
 {
 Hindi = 1, English = 2, Regional = 3
 }
 [Serializable]
 public enum ClassTypes
 {
 PlatinumClass = 1,
 GoldClass = 2,
 Economy = 3
 }
 [Serializable]
 public enum DoYouNeedAMeal
 {
 Yes = 1,
 No = 2
 }
 [Serializable]
 public enum FoodMenu
 {
 Sandwich = 1,
 Noodles = 2,
 Samosa = 3,
 Cookies = 4,
 Juice = 5,
 Tea = 6,
 Coffee = 7
 }

As you can see we have added different enum.

Important Notes:

  • Make sure you select the appropriate name of Enum because it will be automatically reflected in the bot. For example, if you write the name of Enum as MovieTheatreLocation then the bot will use this as:

Please select a movie theatre location

  • Also, note that the sequence of different selection box will depend on how you declare different Enum in code.

For example in above class you have declared Enum in below sequence:

public MovieTheatreLocation movieTheatreLocation;
 public MovieTheatre movieTheatre;
public MovieTypes movieTypes;
public ClassTypes classTypes;
[Optional]
public DoYouNeedAMeal doYouNeedAMeal;
public FoodMenu foodMenu;
public DateTime? DateOfJurney;
[Numeric(1, 5)]
public int? NumberOfAdult;
public int? NumberOfChild;

So Movie theatre selection box will come first and Number of child box will come last.

Now, we need to create a separate dialog for MovieBooking, so add one class called MovieBotDialog:

flow1

In this class, we will write what bot should behave when the user replies something or when the whole conversation is over.

Add code to MovieBotDialog.cs class:

using NeelBotDemo.FormFlow;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.FormFlow;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace NeelBotDemo.Dialogs
{
 public class MovieBotDialog
 {
   public static readonly IDialog<string> dialog = Chain.PostToChain()
   .Select(msg => msg.Text)
   .Switch(
     new RegexCase<IDialog<string>>(new Regex("^hi", RegexOptions.IgnoreCase), (context, text) =>
    {
      return Chain.ContinueWith(new RootDialog(), AfterMyDialogContinue);
    }),
    new DefaultCase<string, IDialog<string>>((context, text) =>
    {
      return Chain.ContinueWith(FormDialog.FromForm(MovieBooking.BuildForm, FormOptions.PromptInStart), AfterMyDialogContinue);
    }))
    .Unwrap()
    .PostToUser();

private async static Task<IDialog<string>> AfterMyDialogContinue(IBotContext context, IAwaitable<object> item)
{
   var token = await item;
   var name = "User";
   context.UserData.TryGetValue<string>("Name", out name);
   return Chain.Return($"Please continue typing if you want to book a movie ticket.");
  }
 }
}

As you can see above, we have mentioned if user types “hi” then we will initiate RootDialog class and in RootDialog class we will write some code to collect the name of the user. RootDialog class will store the name into the context user data, so that the name can be used later in the conversation.

Add code to RootDialog class:

using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Connector;
using System;
using System.Threading.Tasks;

namespace NeelBotDemo.Dialogs
{
  [Serializable]
  public class RootDialog : IDialog
  {
    public async Task StartAsync(IDialogContext context)
    {
      // My dialog initiates and waits for the next message from the user. 
      await context.PostAsync("Hi I am Movie Booking Bot created by Neel.");
      await Respond(context);
      // When a message arrives, call MessageReceivedAsync. 
      context.Wait(MessageReceivedAsync);
    }

   private static async Task Respond(IDialogContext context)
   {
     var userName = string.Empty;
     context.UserData.TryGetValue<string>("Name", out userName);
     if (string.IsNullOrEmpty(userName))
     {
       await context.PostAsync("What is your Name?");
       context.UserData.SetValue<bool>("GetName", true);
     }
     else
     {
       await context.PostAsync(string.Format("Hi {0}.", userName));
     }
  }

  public virtual async Task MessageReceivedAsync(IDialogContext context, IAwaitable<IMessageActivity> result)
  {
    var message = await result;// We've got a message! 
    var userName = String.Empty;
    var getName = false;
    context.UserData.TryGetValue<string>("Name", out userName);
    context.UserData.TryGetValue<bool>("GetName", out getName);
    if (getName)
    {
      userName = message.Text;
      context.UserData.SetValue<string>("Name", userName);
      context.UserData.SetValue<bool>("GetName", false);
    }
    await Respond(context);
    context.Done(message);
  }
 }
}

Once this is done, let us modify MessagesController class which is the heart of the application and our above classes will be called within this controller class.

Write code to MessagesController.cs class:

using NeelBotDemo.Dialogs;
using NeelBotDemo.FormFlow;
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Builder.FormFlow;
using Microsoft.Bot.Connector;
using System.Net;
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;

namespace NeelBotDemo
{
 [BotAuthentication]
 public class MessagesController : ApiController
 {
   /// <summary> 
   /// POST: api/Messages 
   /// Receive a message from a user and reply to it 
   /// </summary> 
   public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
   {
     if (activity.Type == ActivityTypes.Message)
     {
       await Conversation.SendAsync(activity, () => MovieBotDialog.dialog);
     }
    else
    {
      HandleSystemMessage(activity);
    }
   var response = Request.CreateResponse(HttpStatusCode.OK);
   return response;
 }
internal static IDialog<MovieBooking> MakeRootDialog()
{
   return Chain.From(() => FormDialog.FromForm(MovieBooking.BuildForm));
}
private Activity HandleSystemMessage(Activity message)
{
  if (message.Type == ActivityTypes.DeleteUserData)
  {
    // Implement user deletion here 
    // If we handle user deletion, return a real message 
  }
  else if (message.Type == ActivityTypes.ConversationUpdate)
  {
    // Handle conversation state changes, like members being added and removed 
    // Use Activity.MembersAdded and Activity.MembersRemoved and Activity.Action for info 
    // Not available in all channels 
  }
  else if (message.Type == ActivityTypes.ContactRelationUpdate)
  {
    // Handle add/remove from contact lists 
    // Activity.From + Activity.Action represent what happened 
  }
  else if (message.Type == ActivityTypes.Typing)
  {
    // Handle knowing tha the user is typing 
  }
  else if (message.Type == ActivityTypes.Ping)
  {
  }

 return null;
 }
}
}

Whatever response User sends, it will first come to Post method of MessagesController class and then it will invoke MovieBotDialog class.

Our Bot is ready now, just click on start button and you will see below window:

bot9

As I explained in my previous post, we will require a Bot Emulator to test our bot.

So we will start testing our bot by providing our bot URL which is http://localhost:3979/api/messages

Let us test our Bot:

We will start by:

  • Writing hi
  • Bot will greet and will ask your name
  • Once we provide Name, Bot will store our name in user context and will tell us to continue
  • Once we type anything, it will ask to select the city:

flow3

Continue clicking on your selection, a different selection box(forms) will appear which we have given in the class MovieBooking.

Screenshots of Bot for the whole conversation:

flow4

flow5

flow6

flow7

As you can see in above image, whole summery of your inputs have been given, this is awesome.

Say Yes and your booking is successful:

flow8

As you can see the name Neel in the last sentence, it was collected from the user data context.

Congratulations, you have just created a Bot with FromFlow.

Please contact me or write the comment if you have doubt for any of the line of code above.

NOTE – the Whole code is available here.

Hope it helps.

 

 

Naive Bayes in sentiment analysis: Machine Learning Questions & Answers Part – IV

naive6

This is the fourth post on Machine Learning Questions and Answers series. Look here for previous posts.

In this post, we will see some questions related to Naive Bayes Algorithm.

  1. What is Naive Bayes Algorithm?

Answer –

One liner for Naive Bayes Algorithm:

Assuming all the feature are independent and are equally important and predicting the things based on prior knowledge and these independence assumptions.

In other words:

  • The Naive Bayes Algorithm is a Machine Learning Algorithm for Classification problems
  • It is primarily used for text classification
  • A few examples are Sentimental analysis, spam filtration, classifying news articles etc
  • In short, it is a probabilistic classifier

For example:

  • You went to a restaurant for dinner
  • You were told to give a feedback
  • You are quite happy with the experience and gives feedback as “Happy with the food”
  • As per Naive Bayes, all the words given in the feedback are independent of each other and equally important
  • So a Naive Bayes Algorithm can be applied here which will then be matched with some historical data of those words
  • And at the end of the calculation, we can predict whether the feedback given is positive or negative
  • You can get more details in the same post below

2) How could sentimental analysis be used using Naive Bayes Algorithm?

Answer – 

  • For example, our job is to take a comment and classify whether it is a positive or negative comment
  • So we have “comment” as problem instance and Positive or negative as labels
  • As I have explained in my previous posts, to solve above classification problem, we will require a training data which has a large body of texts which are labeled as positive or negative
  • For example word, “Good” would be labeled as Positive and word “Bad” would be labeled as Negative

Next step would be to fit our data to a standard Machine Learning Algorithm, we will use Naive Bayes Algorithm here.

  • In the training phase, the algorithm tries to collect the information to classify any new text as positive or negative
  • Let us assume that we have completed the training phase and it resulted in 55% positive words and 45% negative words
  • So when a new comment comes, we can divide that comment into different words and we can compute a positive score and a negative score for every word

Let us see how a comment can be recognized whether it is a positive comment or a negative comment.

We have below result from our training phase:

naive1

Now a new comment comes and we need to identify whether it is positive or negative.

The comment is “Happy with the Food”

  • Naive Bayes Algorithm will calculate a positivity score and Negativity score
  • It does this using the pieces of information we got from training phase

Let us first calculate the Positivity score for above comment:

  • We will divide the comment into mainly 2 major words, “Happy” and “Food”
  • We can ignore some specific words like “with” “the” etc
  • Positive score can be computed by multiplying Positive score of “Happy” with positive score of “Food” along with the overall probability that the comment is positive

For example:

Below image would explain how to calculate the positive score for the comment “Happy with the Food”:

naive2

As you can see after the multiplication, positive score came as 0.24

Similarly, we can calculate the negative score for the same comment.

Basically Negative score for a word from the training model can be calculated by doing minus from the positive score as explained below:

naive3

So if we try to calculate negative score as we did above then:

naive4

As you can see we got Negative score as 0.02

Here we have taken the example of only 2 words, but it can be computed with n number of words.

Final score is, the comment “Happy with the Food” is positive because positive score 0.24 is greater than Negative score 0.02

naive5

This is how Naive Bayes works with Sentimental Analysis.

3) Why Naive Bayes is called naive?

Answer – 

The Naive Bayes is called Naive because:

  • It makes the assumptions that occurrence of certain features is independent of the occurrence of other features

For example:

  • Your job is to identify the fruit based on its color, shape and taste
  • Then Orange colored, spherical and tangy fruit is most likely be an Orange fruit
  • Even if these features depend on each other, or in the presence of the other features, all these properties individually contribute to the probability that this fruit is Orange
  • For example, if there is a fruit which is orange in shape but it is not spherical in shape and it does not taste tangy but still it could be an Orange fruit

Hope it helps.

 

 

 

 

 

 

 

 

Create a free website or blog at WordPress.com.

Up ↑