Skip to main content

SignalR with Aspnet core 2.2 and angular6

SignalR with Aspnet core 2.2 and angular6

The SignalR server library is included in the Microsoft.AspNetCore.App. 
Next we need to configure our wepapi  to use it. 

in configureservices() section add

 services.AddCors();

in the configure method add

app.UseCors(builder => builder
                .AllowAnyHeader()
                .AllowAnyMethod()
                .SetIsOriginAllowed((host) => true)
                .AllowCredentials()

            );

this is different from core 2.1 as allowanyorigin is not supported with allowcredentials. So we need to either specify which origins to allow for eg:

app.UseCors(builder =>
            {
                builder.WithOrigins("http://localhost:4200")
                .AllowAnyHeader().AllowAnyMethod().AllowCredentials();

            });
or we can use 

.SetIsOriginAllowed((host) => true)

Next is to create a Hub.

public class MessageHub: Hub
    {

    }

My Hub class doesnt contain anything. We need to inherit from the Hub class which will give it some special properties to call the client side functions from the server.
In my WebApi I have created a very simple endpoint that returns a random name from a predefined list. This name will be sent to the angular app which will display it on the server. So the server code looks something like this.

I have created a controller called Home that has an action named GetRandomNames() that returns a random name.



create an instance of the hub through dependency as follows.

private readonly IHubContext<MessageHub> _hub;

        public HomeController(IHubContext<MessageHub> hub)
        {
            _hub = hub;
        } 

we can call the client side function called "addNewItem" through this _hub property.

this._hub.Clients.All.SendAsync("addNewItem",name);

this will send the random name to all connected clients. The hub property has several other methods through which we can send data to selected or even a single client also.

Once we run visual studio we will get the URL from which we can access the API. In my case its https://localhost:44330/.

Client Side Configuration

Used VsCode for the client side part, also to demonstrate how to use CORS.

create an angular app using the angular cli

ng new sample SignalrSample

once project is created run 

npm install 

appcomponent.html 

<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</div>
<h2>Here are some links to help you start: </h2>
<ul class="heroes">
<li *ngFor="let emp of empList">
<span class="badge">{{ emp }}</span>
</li>
</ul>
<div>
<input type="button" value="add new" (click)="getNewName()">
</div>



appcomponent.ts

import { Component, OnInit } from '@angular/core';
import {HubConnection, HubConnectionBuilder } from '@aspnet/signalr';
import { HttpClient } from '@angular/common/http';

@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
title = 'signalr sample using aspnet core 2.2 and angular 6';
empList:string[]=["papa","mummy"];

constructor(private http: HttpClient) { }

ngOnInit(): void {
var connection =new HubConnectionBuilder().withUrl("https://localhost:44330/messageHub").build();
connection.on("addNewItem",data=>{
this.empList.push(data);
});

connection.start().then(()=>alert("Connected to server.."))

// connection.start()
// .then(()=>connection.invoke("connected","connected to WebApi"))
// .catch(function (err) {
// return console.error(err.toString());
// });
}

getNewName():void{
this.http.get("https://localhost:44330/home/GetRandomNames").subscribe(function(result){
})
}
}


appmodule.ts

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';

import { AppComponent } from './app.component';

@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [HttpClientModule],
bootstrap: [AppComponent]
})
export class AppModule { }


Now run the API and use the below command to start the angular app
ng serve

Need to be in the directory where the package.json resides for ng-serve to work



open localhost:4200 on different tabs and click the button 


the new name will be seen on each browser 





Comments

Popular posts from this blog

App Role assignment to service principal --

 Using Ms Graph Rest API's Permissions One of the following permissions is required to call this API. To learn more, including how to choose permissions, see  Permissions . Permission type Permissions (from least to most privileged) Delegated (work or school account) AppRoleAssignment.ReadWrite.All and Application.Read.All, AppRoleAssignment.ReadWrite.All and Directory.Read.All, Application.ReadWrite.All, Directory.ReadWrite.All Delegated (personal Microsoft account) Not supported. Application AppRoleAssignment.ReadWrite.All and Application.Read.All, AppRoleAssignment.ReadWrite.All and Directory.Read.All, Application.ReadWrite.All, Directory.ReadWrite.All Create 2 app registrations. App role owner will contain the app role that will be assigned to a service principal. The  reader role in approleowner will be added to the approlesubscriber Setup postman to use the Oauth auth flow to get a token for MS Graph. ClientId:   Application (client) ID for approlesubscrib...

ASp.net core 3.1 identity

It is just an extension to cookie authentication. We get a UI, Tables, helper classes, two factor authentication etc. Even EF and its database constructs. So instead of writing code for all of this we can just use these in built features. Extending Default Identity Classes Add a class that inherits from    public class AppUser : IdentityUser     {         public string Behavior { get; set; }     } Also change the user type in login partial.cs under shared folder Then add migrations and update db using migrations. We can customize further.  services.AddDefaultIdentity<AppUser>(options =>              {                 options.SignIn.RequireConfirmedAccount = true;                 options.Password.RequireDigit = false;           ...

Get user groups

 string[] scopes = new string[] { "https://graph.microsoft.com/.default" };             string clientId = "";             string tenantId = "";             string secret = "";                        var options = new TokenCredentialOptions             {                 AuthorityHost = AzureAuthorityHosts.AzurePublicCloud             };             // https://learn.microsoft.com/dotnet/api/azure.identity.clientsecretcredential             try             {                 var clientSecretCredential = new ClientSecretCredential(                        ...