Wednesday, August 16, 2023

A Deep Dive into Computed Columns in Entity Framework Core

Entity Framework Core (EF Core) is a popular Object-Relational Mapping (ORM) framework that simplifies database access for .NET applications. It provides a wide range of features to map your C# classes to database tables and manage the interaction between your application and the underlying database. One powerful feature of EF Core is its support for computed columns, which allow you to define columns in your database that are computed based on other columns' values. In this article, we'll explore the concept of computed columns in EF Core, their benefits, and how to work with them effectively.



Understanding Computed Columns

A computed column is a column in a database table that is calculated based on an expression involving other columns in the same table. Unlike regular columns that store data explicitly provided by users, computed columns derive their values from existing data within the table. This can be incredibly useful for performing calculations or transformations on data without having to retrieve it first and then calculate in your application code.

  1. Computed columns offer several advantages:

  2. Data Consistency: Since computed column values are calculated based on other columns' values, you can ensure consistency in derived data without relying on developers to perform calculations correctly.

  3. Performance: Calculations performed at the database level can be optimized for better performance, especially when dealing with large datasets.

  4. Readability: Computed columns can simplify complex calculations, making your queries and code more readable.

  5. Maintenance: When business logic changes, you only need to update the computed column expression in the database, minimizing code changes.

Using Computed Columns in EF Core

In EF Core, you can define computed columns using the .HasComputedColumnSql() method in your entity configuration. Let's walk through an example of creating a TotalPrice computed column for an Order entity.

Assuming you have an Order entity with a Quantity column and a UnitPrice column, you can calculate the total price using the following code:

public class Order { public int OrderId { get; set; } public int Quantity { get; set; } public decimal UnitPrice { get; set; } public decimal TotalPrice { get; private set; } // Computed column // Other properties and methods } public class MyDbContext : DbContext { public DbSet<Order> Orders { get; set; } protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Order>() .Property(o => o.TotalPrice) .HasComputedColumnSql("[Quantity] * [UnitPrice]"); } }
In this example, the TotalPrice property's value is calculated by multiplying Quantity and UnitPrice. The .HasComputedColumnSql() method takes an SQL expression as a parameter.


Note: Computed columns are supported in various database systems, but the syntax might differ. Be aware of any compatibility issues when working with different databases.

Saturday, May 6, 2023

How to explore/test API endpoints by Visual Studio

By integrating new tools, Visual Studio is changing in a remarkable way every day. One such tool that can make our life easier is the Visual Studio API Endpoint Explorer. This powerful tool allows you to explore and test API endpoints, making it an essential part of any developer's toolkit. What is the Visual Studio API Endpoint Explorer? The Visual Studio API Endpoint Explorer is a tool that allows developers to explore and test API endpoints. It provides a user-friendly interface that makes it easy to navigate through different endpoints and test them with different parameters. The tool supports a wide range of HTTP methods, including GET, POST, PUT, DELETE, and more. NOTE: This capability is available starting with the below version and later of Visual Studio. Microsoft Visual Studio Community 2022 (64-bit) - Preview Version 17.6.0 Preview 6.0

How to Use the Visual Studio API Endpoint Explorer?

To let you explore and interact with the API endpoints specified in the solution, we are working on a new preview tool called the Endpoints Explorer. As this is a preview feature, it must be turned on in order for us to see it. Go to Tools > Options > Environment > Preview Features and choose the Web API Endpoints Explorer to enable the new Tool Window. To narrow down the options, utilize the search text box in that dialog. View the picture below.


After enabling the feature, you have to open the C# web application where the API endpoint exists. You may access the Endpoints Explorer now that you've enabled it by selecting View > Other Windows > Endpoints Explorer. You should see the window similar to what is seen in the following image once you have opened that window. 
If you click Generate Request in this window, an HTTP file will also be generated along with the request. Below is the outcome for the /weatherforecast request after calling that context menu.




Monday, February 13, 2023

Building Umbraco 11 with dotnet 7 and running the web app in docker container

 Building Umbraco 11 with dotnet 7 and running the web app in the docker container

Since its original release in March 2013, Docker has been around and has truly impacted the structure of web apps and services and how applications are deployed and scaled.

In our world of content management websites, it hasn't nearly had the same effect, and I believe we're missing out on some excellent chances to make the sites we develop faster, more effective, more scalable, and more durable. In this post, I'll walk you through how to achieve this.

Prerequisites

In order to run this application you will need the following installed on your machine.

  • Visual Studio Code
  • WSL2
    • Windows Subsystem for Linux
  • .NET SDK version 7
    • This will also work with the earlier version .NET version core, but you need a compatible SDK
  • Docker Desktop
    • The best solution if you're using Windows or a Mac is Docker desktop, a free (for individuals) program offered by Docker that simply configures everything for you. It takes some effort to set up Docker on Linux. I won't go through particular instructions for each platform here, but you can find some pretty decent information on how to do it here: https://docs.docker.com/desktop/windows/install/ and https://docs.docker.com/get-docker/
  • Few key concepts of Docker
    • What is Docker, Docker Image, Docker Container, Container Registry, Dockerfile, and Docker Networking are a few fundamental concepts.

Anyone can find the code-base from the Github repo here.

Steps to follow:

  1. Start with a simple Umbraco website.
  2. Make an MSSQL database instance running on Docker container.
  3. Make the application container and have them communicate with one another.

Building an Umbraco container application

Let's start from scratch and build a brand-new standalone Umbraco application on our local machine. This Umbraco 11 site will be backed by .NET 7.

Install the Umbraco templates first and then create a new solution named “MyUmbracoAppOnDocker” and then add the project to the solution, and install a starter kit

Open the command window in elevated mode and run below commands

dotnet new -i Umbraco.Templates::11
dotnet new sln --name MyUmbracoAppOnDocker
dotnet new umbraco -n MyUmbracoAppOnDocker --friendly-name "Admin User" --email "admin@umbraco.com" --password "1234567890" --connection-string "Data Source=(localdb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\MyUmbracoAppOnDockerData.mdf;Integrated Security=True"
dotnet sln MyUmbracoAppOnDocker.sln add MyUmbracoAppOnDocker
dotnet add MyUmbracoAppOnDocker package Clean

Now run the site by following command and it will create new localDB

dotnet run --project MyUmbracoAppOnDocker

 

We can see what port the site is using in the output, and we can launch the website in any browser of choice. This step must be finished to build the Database.

The project is now running locally on the development workstation as an ordinary Umbraco site.



Now it’s time to Run the database from a container.


Stop the running application before running the below command.

mkdir UmbracoData;
$currDir = Get-Location; Copy-Item -Path $currDir/MyUmbracoAppOnDocker/umbraco/Data/MyUmbracoAppOnDockerData.mdf -Destination $currDir/UmbracoData -PassThru;
$currDir = Get-Location; Copy-Item -Path $currDir/MyUmbracoAppOnDocker/umbraco/Data/MyUmbracoAppOnDockerData_log.ldf -Destination $currDir/UmbracoData -PassThru;

 

Now we will create three files in newly created folder “UmbracoData”

1.         startup.sh

2.         setup.sql

3.         Dockerfile

 

To start the MSSQL database, we will now create a bash program called Startup.sh, which we will call from a Docker file. The main job of startup.sh is to start setup.sql as the server admin (or sa) account and sleep for 15 seconds while the sql server is starting up. We have to define the password here.

#!/bin/bash
set -e
 
if [ "$1" = '/opt/mssql/bin/sqlservr' ]; then
# If this is the container's first run, initialize the application database
if [ ! -f /tmp/app-initialized ]; then
    # Initialize the application database asynchronously in a background process. This allows a) the SQL Server process to be the main process in the container, which allows graceful shutdown and other goodies, and b) us to only start the SQL Server process once, as opposed to starting, stopping, then starting it again.
    function initialize_app_database() {
    # Wait a bit for SQL Server to start. SQL Server's process doesn't provide a clever way to check if it's up or not, and it needs to be up before we can import the application database
    sleep 15s
 
    #run the setup script to create the DB and the schema in the DB
    /opt/mssql-tools/bin/sqlcmd -S localhost -U sa -P Abcd!234 -d master -i setup.sql
 
    # Note that the container has been initialized so future starts won't wipe changes to the data
    touch /tmp/app-initialized
    }
    initialize_app_database &
fi
fi
exec "$@"

 

The setup.sql file looks like:

 

USE [master]
GO
 
IF NOT EXISTS (SELECT * FROM sys.databases WHERE name = 'MyUmbracoAppOnDockerDB')
BEGIN
 
    CREATE DATABASE [MyUmbracoAppOnDockerDB] ON
    ( FILENAME = N'/var/opt/sqlserver/MyUmbracoAppOnDockerData.mdf' ),
    ( FILENAME = N'/var/opt/sqlserver/MyUmbracoAppOnDockerData_log.ldf' )
    FOR ATTACH
 
END;
GO
 
USE MyUmbracoAppOnDockerDB;

 

Now we will create a Dockerfile that describes the Database server that will run on Docker. The first line in Dockerfile describes the image that will be used: SQL Server 2019 that running on Ubuntu. After that we will define the password for SA account.

FROM mcr.microsoft.com/mssql/server:2019-GDR1-ubuntu-16.04
ENV ACCEPT_EULA=Y
ENV SA_PASSWORD=Abcd!234
ENV MSSQL_PID=Express
 
USER root
 
RUN mkdir /var/opt/sqlserver
 
RUN chown mssql /var/opt/sqlserver
 
ENV MSSQL_BACKUP_DIR="/var/opt/sqlserver"
ENV MSSQL_DATA_DIR="/var/opt/sqlserver"
ENV MSSQL_LOG_DIR="/var/opt/sqlserver"
 
COPY setup.sql /
COPY startup.sh /
 
COPY MyUmbracoAppOnDockerData.mdf /var/opt/sqlserver
COPY MyUmbracoAppOnDockerData_log.ldf /var/opt/sqlserver
 
ENTRYPOINT [ "/bin/bash", "startup.sh" ]
CMD [ "/opt/mssql/bin/sqlservr" ]

 

Go back to our Umbraco project now and change the connection string to link to this SQL server that are running on Docker. Modify the app settings. According to appsettings.Development.json

"ConnectionStrings": {
    "umbracoDbDSN": "Server=localhost,1401;Database= MyUmbracoAppOnDockerDB;User Id=sa;Password=Abcd!234;"
  }

 

Note: Because it's likely you already have MSSQL Server installed locally and using port 1433 would cause a problem, we're utilizing port 1400 instead of the standard 1433.

 

Now we will create the MSSQL Docker image by using the command.

docker build --tag=umbracodata .\UmbracoData

It will create a database image in local docker host.





After creating this docker image, it’s time to run the docker SQL server by executing below command. Again, take notice of the port that is being used, while the Docker image still uses 1433 internally, 1401 is used externally to avoid conflict with any other local SQL servers.

docker run --name umbracodata -p 1401:1433 --volume sqlserver:/var/opt/sqlserver -d umbracodata

 It will create a MSSQL container from the image umbracodata

 

Verify that the website is still functional.

Now we will run the Umbraco application locally by pointing the database serving from Docker. The command window will once again show which port should be used to access the site.

dotnet run --project MyUmbracoAppOnDocker

 

Now it’s time to create another docker file to Run the application in Docker.

We must add a new file called Dockerfile inside the root of our web project in order to start the project in Docker.

# Use the SDK image to build and publish the website
FROM mcr.microsoft.com/dotnet/sdk:7.0 AS build
WORKDIR /src
COPY ["MyUmbracoAppOnDocker.csproj", "."]
RUN dotnet restore "MyUmbracoAppOnDocker.csproj"
COPY . .
RUN dotnet publish "MyUmbracoAppOnDocker.csproj" -c Release -o /app/publish
 
# Copy the published output to the final running image
FROM mcr.microsoft.com/dotnet/aspnet:7.0 AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "MyUmbracoAppOnDocker.dll"]
 

This section will describes that most developers struggle with is the Docker Networking.

We must have a basic understanding of Docker networking before we can run the fully functional website in a container. In Docker, containers will communicate via a variety of networking protocols. One of those is Bridge networks, which come in both default and user-defined Bridge network.

Any container may connect with any other container on the default bridge network to which all containers are can communicate if none are specified. However, it can only do so using IP addresses, which are assigned dynamically.

Containers can use the name of the network to interact in a user-defined bridge network, but only containers that have been explicitly added to the network can use the container name to connect with one another.

We will create a user-defined Bridge network first and then attach the network with the previously created database container by using the container name (umbracodata). Stop the running web application if it's still active by pressing Ctrl + C.

docker network create -d bridge umbracoNetwork
docker network connect umbracoNetwork umbracodata

 

Connectionstring for Application Container:

Create an appsettings.Staging.config file by coping the content of current appsettings.Development.json  file and replace the connectionstring as below. This is necessary to use nonstandard port. Important part is Server=umbracodata where umbracodata is the name of the database container.

"umbracoDbDSN": "Server=umbracodata;Database=MyUmbracoAppOnDockerDB;User Id=sa;Password=Abcd!234;"

 

This stage we will Create the application container image.

We can create our application image now by running the below command. Our database container is running and attached to the user-defined network umbracoNetwork.

docker build --tag=umbracoappondocker .\MyUmbracoAppOnDocker

This command will create Docker image of the Umbraco application. Observe that the web image is not being used, but you can see that the database image is being used since it is now operating.

 

 


 

Now we can create a container from umbracoappondocker image for our Umbraco application on Docker container.

docker run --name umbracoappondocker -p 8000:80 -v media:/app/wwwroot/media -v logs:/app/umbraco/Logs -e ASPNETCORE_ENVIRONMENT='Staging' --network=umbracoNetwork -d umbracoappondocker

 

 

Closure

In this tutorial, we've generated two containers and run them locally on our Docker instance, one for our Umbraco 11 application and the other for the MSSQL database server and they can communicate each other by user defined Bridge network. We've discussed networking, Docker images, and some of the prerequisites for getting things up and running.

 

Happy coding!

Saturday, January 28, 2023

Why should you avoid making async void methods? Make the methods instead return Task.

 Why should you avoid making async void methods? Make the methods instead return Task.

  • 1. Processes are always crashed by exceptions thrown by async void methods.
  • 2. Even the option to wait for the result is not available to callers.
  • 3. The caller cannot report exceptions to telemetry.
  • 4. If your VS package was started in this manner, it is unable to be responsibly blocked in Package.Close until your async work is complete.
  • 5. Use caution: when passing an async delegate or async () => become async void methods when passed to a method that accepts Action delegates. If a method accepts Func<Task> or Func<Task<T>> parameters, only pass async delegates to those methods.

Wednesday, December 28, 2022

A few key terminology and technology in Authentication and Authorization


SSO:
A Single-Sign-On feature that enables users to sign in only once to access numerous applications within an organization after being authenticated using a single set of credentials. For instance, logging into mail.google.com will give you access to www.youtube.com.

Federated Authentication: SSO plus, the ability to authenticate across multiple organizations. For example, signing into Microsoft may grant you access to Salesforce, Atlassian, and other services. There are a number of different authentication protocols and standards, including OpenID Connect, OAuth, and SAML. Federated authentication standardizes the authentication communication cycle using one or more protocols.

OWIN: OWIN is a specification that enables decoupling web applications from web servers. It establishes a uniform method for using middleware in a pipeline to manage requests and related responses. Microsoft offers a version of OWIN called Katana that is provided as NuGet packages under the name Microsoft.Owin.* (https://github.com/aspnet/AspNetKatana).

ASP.NET Identity: Since the introduction of the ASP.NET membership system with ASP.NET 2.0 in 2005, there have been numerous modifications to how web applications typically handle authentication and authorization. When developing cutting-edge apps for online, mobile devices, or tablets, ASP.NET Identity offers a new perspective on what the membership system ought to be.

Duende IdentityServer: IdentityServer4 End-of-life (EOL) - What Next? Duende IdentityServer, The most adaptable and compatible OAuth 2.0 and OpenID Connect framework for ASP.NET Core. IdentityServer gives you full control over your UI, UX, business logic, and data.

Sunday, December 3, 2017

Json Web Token (JWT) based authentication by using ASP.Net Web API with the help of OWIN middle-ware, ASP .Net Identity and AngularJs Client app. Part 02.

This is the second part of "Json Web Token (JWT) based authentication by using ASP.Net Web API with the help of OWIN middle-ware, ASP .Net Identity and AngularJs Client app. Part 02.", you can find the first part using this link

In this post we will build a Singe Page AngularJS Application named "Client Management Application" where we will display a list of clients.

Now I will explain how this client application communicate with our previously build resource server. By this application user could able to do below functionality.

  1. User could Register to the authorization server by providing username and password.
  2. Allow the user to logged in to the Authorization server and getting the access token for granting access to the secure resource.
  3. View the secure data by providing the bearer access token.

It is required to understand the minimum concept of AngularJS before start working with this client application.

You could download the complete source-code from here.
In this application we are using some third party angular client library.


Steps to prepare Client application:

Step 1:
Add an empty project in the solution named "AngularClientApplication". Folder structure of the app as like below.




































Step 2:
Add Index.html page as it will be the first page when boot the application. We will reference all Javascript and Css libraries to this page.
<!DOCTYPE html>
<html ng-app="angularApp">
<head>
    <title>Angular Client Application</title>
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link href="Content/bootstrap.css" rel="stylesheet" />
    <link href="Content/animations.css" rel="stylesheet" />
    <link href="Content/styles.css" rel="stylesheet" />
</head>
<body ng-cloak>
    <header class="navbar navbar-inner navbar-fixed-top" ng-controller="navbarController">
        <nav class="container">
            <div class="navbar-header">
                <button type="button" class="navbar-toggle" ng-click="isCollapsed = !isCollapsed">
                    <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" href="#/">
                    <img src="Content/images/people.png" alt="logo">
                    <span class="appTitle">{{ appTitle }}</span>
                </a>
            </div>
            <div class="nav-container" data-collapse="vm.isCollapsed">
                <ul class="nav navbar-nav nav-pills navBarPadding" menu-highlighter highlight-class-name="active">
                    <li><a href="#/clients">Clients</a></li>
                    <li><a href="#/about">About</a></li>
                    <li data-ng-hide="!authentication.isAuthenticated"><a href="" data-ng-click="logOut()">Logout</a></li>
                    <li data-ng-hide="authentication.isAuthenticated"> <a href="#/login">Login</a></li>
                    <li data-ng-hide="authentication.isAuthenticated">
                        <a href="#/signup">Sign up</a>
                    </li>
                </ul>
            </div>
        </nav>
    </header>
    <div class="slide-animation-container">
        <div ng-view id="ng-view" class="slide-animation"></div>
    </div>
    <div id="footer">
        <div class="navbar navbar-fixed-bottom">
            <div class="navbar-inner footer">
                <div class="container text-center">
                    <footer>
                        <div class="row">
                            <div class="col-md-12">
                                Created by : <a href="https://www.linkedin.com/in/md-towhidul-islam-04513455/" target="_blank">Towhidul Tuhin</a>
                            </div>
                        </div>
                    </footer>
                </div>
            </div>
        </div>
    </div>

    <!-- 3rd party libraries -->
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-route.min.js"></script>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular-animate.min.js"></script>
    <script src="Scripts/lib/angular-ui-bootstrap.js"></script>
    <script src="Scripts/lib/angular-local-storage.min.js"></script>

    <!-- Custom scripts -->
    <script src="Scripts/app/angularApp.js"></script>
    <script src="Scripts/app/navbarController.js"></script>
    <script src="Scripts/app/security/controllers/aboutController.js"></script>
    <script src="Scripts/app/security/controllers/loginController.js"></script>
    <script src="Scripts/app/security/controllers/signupController.js"></script>
    <script src="Scripts/app/security/services/authInterceptorService.js"></script>
    <script src="Scripts/app/security/services/authService.js"></script>

    <script src="Scripts/app/client/controllers/clientsController.js"></script>
    <script src="Scripts/app/client/services/clientsService.js"></script>
</body>
</html>

As you see above html page, angular will be boot by the module "angularApp".

Step 2:
Add angular libraries "angular-local-storage.min.js" and "angular-ui-bootstrap" to the location "Scripts\lib\". angular-local-storage will be used to store the token value in Html 5 local storage.

Step 3:
Add initial js file "angularApp.js" to location "Scripts\app\". This file will consist of "angularApp" module and the route configuration.
var app = angular.module('angularApp', ['ngRoute', 'ui.bootstrap', 'LocalStorageModule']);

app.config(function ($routeProvider) {

    $routeProvider.when("/home", {
        templateUrl: "/Scripts/app/views/home.html"
    });

    $routeProvider.when("/login", {
        controller: "loginController",
        templateUrl: "/Scripts/app/views/login.html"
    });

    $routeProvider.when("/signup", {
        controller: "signupController",
        templateUrl: "/Scripts/app/views/signup.html"
    });

    $routeProvider.when("/clients", {
        controller: "clientsController",
        templateUrl: "/Scripts/app/views/clients.html"
    });

    $routeProvider.when("/about", {
        controller: "aboutController",
        templateUrl: "/Scripts/app/views/about.html"
    });

    $routeProvider.otherwise({ redirectTo: "/home" });

});

var serviceBase = 'http://localhost:59598/';
app.constant('ngAuthSettings', {
    apiServiceBaseUri: serviceBase,
    clientId: 'IAmTheFirstClient'
});

app.config(function ($httpProvider) {
    $httpProvider.interceptors.push('authInterceptorService');
});

app.run(['authService', function (authService) {
    authService.fillAuthData();
}]);
Above code-block holds all route configuration and a constant value "ngAuthSettings" which hold our authorization server base url and client id. One important things is configured here which is angular http interceptor. This interceptor is responsible to configure a XHR request before sending the request to the server.

Set 4:
Add a controller "navbarController.js" to the location "Scripts\app\". This controller will hold the Login and Log out function.
(function () {

    var injectParams = ['$scope', '$location', 'authService'];

    var NavbarController = function ($scope, $location, authService) {
            $scope.appTitle = 'Client Management';
            $scope.authentication = authService.authentication;

        $scope.logOut = function () {
                var isAuthenticated = authService.authentication.isAuthenticated;
                if (isAuthenticated) { //logout 
                    authService.logOut();
                    $location.path('/');
                    return;
                }
            };

        $scope.login = function () {
            var path = '/login';
            $location.replace();
            $location.path(path);
        };

    };

    NavbarController.$inject = injectParams;

    angular.module('angularApp').controller('navbarController', NavbarController);

}());

Step 5:
Add a factory service "authInterceptorService.js" to the location "Scripts\app\security\services". 
'use strict';
app.factory('authInterceptorService', ['$q', '$injector','$location', 'localStorageService', function ($q, $injector,$location, localStorageService) {

    var authInterceptorServiceFactory = {};

    var _request = function (config) {

        config.headers = config.headers || {};
       
        var authData = localStorageService.get('authorizationData');
        if (authData) {
            config.headers.Authorization = 'Bearer ' + authData.token;
        }

        return config;
    }

    var _responseError = function (rejection) {
        if (rejection.status === 401) {
            var authService = $injector.get('authService');
            var authData = localStorageService.get('authorizationData');

            if (authData) {
                if (authData.useRefreshTokens) {
                    $location.path('/refresh');
                    return $q.reject(rejection);
                }
            }
            authService.logOut();
            $location.path('/login');
        }
        return $q.reject(rejection);
    }

    authInterceptorServiceFactory.request = _request;
    authInterceptorServiceFactory.responseError = _responseError;

    return authInterceptorServiceFactory;
}]);
This service will be responsible to inject some configuration to the XHR request before going it to the actual server.

Step 6:
Add another factory service "authService.js" to the same folder mentioned above. This service will be responsible to API call like user registration, token generation, store the token in local storage after validation.
'use strict';
app.factory('authService', ['$http', '$q', 'localStorageService', 'ngAuthSettings', function ($http, $q, localStorageService, ngAuthSettings) {

    var serviceBase = ngAuthSettings.apiServiceBaseUri;
    var authServiceFactory = {};

    var _authentication = {
        isAuthenticated: false,
        userName: "",
        useRefreshTokens: false
    };

    var _saveRegistration = function (registration) {

        _logOut();

        return $http.post(serviceBase + 'api/account/register', registration).then(function (response) {
            return response;
        });

    };

    var _login = function (loginData) {

        var data = "grant_type=password&username=" + loginData.userName + "&password=" + loginData.password + "&client_id=" + ngAuthSettings.clientId;
        
        var deferred = $q.defer();

        $http.post(serviceBase + 'security/token', data, { headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }).success(function (response) {

            if (loginData.useRefreshTokens) {
                localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName, refreshToken: response.refresh_token, useRefreshTokens: true });
            }
            else {
                localStorageService.set('authorizationData', { token: response.access_token, userName: loginData.userName, refreshToken: "", useRefreshTokens: false });
            }
            _authentication.isAuthenticated = true;
            _authentication.userName = loginData.userName;
            _authentication.useRefreshTokens = loginData.useRefreshTokens;

            deferred.resolve(response);

        }).error(function (err, status) {
            _logOut();
            deferred.reject(err);
        });

        return deferred.promise;

    };

    var _logOut = function () {

        localStorageService.remove('authorizationData');

        _authentication.isAuthenticated = false;
        _authentication.userName = "";
        _authentication.useRefreshTokens = false;

    };

    var _fillAuthData = function () {

        var authData = localStorageService.get('authorizationData');
        if (authData) {
            _authentication.isAuthenticated = true;
            _authentication.userName = authData.userName;
            _authentication.useRefreshTokens = authData.useRefreshTokens;
        }

    };

    authServiceFactory.saveRegistration = _saveRegistration;
    authServiceFactory.login = _login;
    authServiceFactory.logOut = _logOut;
    authServiceFactory.fillAuthData = _fillAuthData;
    authServiceFactory.authentication = _authentication;

    return authServiceFactory;
}]);

Step 7:
Add "signupController.js" controller to the location "Scripts\app\security\controllers". This controller will be responsible to register an User.
'use strict';
app.controller('signupController', ['$scope', '$location', 'authService', function ($scope, $location, authService) {

    $scope.savedSuccessfully = false;
    $scope.message = "";

    $scope.registration = {
        name: "",
        password: "",
        confirmPassword: ""
    };

    $scope.signUp = function () {

        authService.saveRegistration($scope.registration).then(function (response) {

            $scope.savedSuccessfully = true;
            $scope.message = "User has been registered successfully";
            $location.path('/login');

        },
         function (response) {
             var errors = [];
             for (var key in response.data.modelState) {
                 for (var i = 0; i < response.data.modelState[key].length; i++) {
                     errors.push(response.data.modelState[key][i]);
                 }
             }
             $scope.message = "Failed to register user due to:" + errors.join(' ');
         });
    };

}]);

Step 8:
Add "loginController.js" controller to the location "Scripts\app\security\controllers". This controller will responsible to login the user to the system.
'use strict';
app.controller('loginController', ['$scope', '$location', 'authService', 'ngAuthSettings', function ($scope, $location, authService, ngAuthSettings) {

    $scope.loginData = {
        userName: "",
        password: "",
        useRefreshTokens: false
    };

    $scope.message = "";

    $scope.login = function () {

        authService.login($scope.loginData).then(function (response) {
            
            $location.path('/clients');

        },
         function (err) {
             $scope.message = err.error_description;
         });
    };
}]);

Step 9:
Add "clientsController.js" controller to the location "Scripts\app\client\controllers". This controller will be responsible for calling a getClients sevice.
'use strict';
app.controller('clientsController', ['$scope', 'clientsService', function ($scope, clientsService) {

    $scope.clients = [];

    clientsService.getClients().then(function (results) {

        $scope.clients = results.data;

    }, function (error) {
    });

}]);
Step 10:
Add "clientsService.js" controller to the location "Scripts\app\client\services". This service is responsible for retrieve client data from the resource serve by a XHR request.
'use strict';
app.factory('clientsService', ['$http', 'ngAuthSettings', function ($http, ngAuthSettings) {

    var serviceBase = ngAuthSettings.apiServiceBaseUri;

    var clientsServiceFactory = {};

    var _getClients = function () {

        return $http.get(serviceBase + 'api/clients').then(function (results) {
            return results;
        });
    };

    clientsServiceFactory.getClients = _getClients;

    return clientsServiceFactory;

}]);

Step 11:
Add view "signup.html" to the location "Scripts\app\views". This view will render for register an user.
<div class="view">
    <div class="container">
        <header>
            <h3><span class="glyphicon glyphicon-lock"></span> Sign up</h3>
        </header>
        <form name="loginForm" novalidate>
            <div class="login">
                <div class="row">
                    <div class="col-md-2">
                        User Name:
                    </div>
                    <div class="col-md-10">
                        <input type="text" name="userName" class="form-control" data-ng-model="registration.name" required />
                        <span class="errorMessage" ng-show="loginForm.userName.$touched && loginForm.userName.$invalid">
                            User Name is required
                        </span>
                    </div>
                </div>
                <br />
                <div class="row">
                    <div class="col-md-2">
                        Password:
                    </div>
                    <div class="col-md-10">
                        <input type="password" name="password" class="form-control"
                               data-ng-model="registration.password"
                               data-ng-minlength="6"
                               required />
                        <span class="errorMessage" ng-show="loginForm.password.$touched && loginForm.password.$invalid">
                            Password is required
                        </span>
                    </div>
                </div>
                <br />
                <div class="row">
                    <div class="col-md-2">
                        Confirm Password:
                    </div>
                    <div class="col-md-10">
                        <input type="password" name="confirmPassword" class="form-control"
                               data-ng-model="registration.confirmPassword"
                               data-ng-minlength="6"
                               required />
                        <span class="errorMessage" ng-show="loginForm.password.$touched && loginForm.password.$invalid">
                            Confirm password is required
                        </span>
                    </div>
                </div>
                <br />
                <div class="row">
                    <div class="col-md-12">
                        <button type="submit" class="btn btn-primary"
                                data-ng-click="signUp()"
                                ng-disabled="loginForm.$invalid || !loginForm.$dirty">
                            Save
                        </button>
                    </div>
                </div>
                <br />
                <div class="statusRow">
                    <br />
                    <div class="label label-important" data-ng-show="errorMessage">
                        <span class="glyphicon glyphicon-thumbs-down icon-white"></span>&nbsp;&nbsp;Error: {{ errorMessage }}
                    </div>
                </div>
            </div>
        </form>
    </div>
</div>
Step 12:
Add view "login.html" to the location "Scripts\app\views". This view will render for login an user to the system.
<div class="view">
    <div class="container">
        <header>
            <h3><span class="glyphicon glyphicon-lock"></span> Login</h3>
        </header>
        <form name="loginForm" novalidate>
            <div class="login">
                <div class="row">
                    <div class="col-md-2">
                        User Name:
                    </div>
                    <div class="col-md-10">
                        <input type="text" name="userName" class="form-control" data-ng-model="loginData.userName" required />
                        <span class="errorMessage" ng-show="loginForm.userName.$touched && loginForm.userName.$invalid">
                            User Name is required
                        </span>
                    </div>
                </div>
                <br />
                <div class="row">
                    <div class="col-md-2">
                        Password:
                    </div>
                    <div class="col-md-10">
                        <input type="password" name="password" class="form-control"
                               data-ng-model="loginData.password"
                               data-ng-minlength="6"
                               required />
                        <span class="errorMessage" ng-show="loginForm.password.$touched && loginForm.password.$invalid">
                            Password is required
                        </span>
                    </div>
                </div>
                <br />
                <div class="row">
                    <div class="col-md-2">
                    </div>
                    <div class="col-md-10">
                        <button type="submit" class="btn btn-primary"
                                data-ng-click="login()"
                                ng-disabled="loginForm.$invalid || !loginForm.$dirty">
                            Login
                        </button>
                        <a href="/#/signup">Sign up</a>
                    </div>
                </div>
                <br />
                <div class="statusRow">
                    <br />
                    <div class="label label-important" data-ng-show="errorMessage">
                        <span class="glyphicon glyphicon-thumbs-down icon-white"></span>&nbsp;&nbsp;Error: {{ errorMessage }}
                    </div>
                </div>
            </div>
        </form>
    </div>
</div>
Step 13:
Add view "home.html" to the location "Scripts\app\views". This view contain a placeholder for home page.
    <div class="row">
        <div class="jumbotron">
            <div class="container">
                <div class="page-header text-center">
                    <h1>Json Web Token(JWT) base Authentication</h1>
                </div>
                <p>REST Web API Application which is responsible for generating OAuth Bearer Token(JWT) and authentication and authorization. This backend API is fully stateless and built using ASP.NET Web API 2, OWIN middleware, and ASP.NET Identity. AngularJs as the client application.</p>
            </div>
        </div>
    </div>
Step 14:
Add view "clients.html" to the location "Scripts\app\views". This view render for showing list of clients.
<div class="clients view indent">
    <div class="container">
        <header>
            <h3><span class="glyphicon glyphicon-user"></span> clients</h3>
        </header>
        <div class="container">
            <div class="row gridContainer clientsTable show-hide-animation">
                <div class="col-md-10">
                    <div>
                        <table class="table table-striped table-condensed">
                            <thead>
                                <tr>
                                    <th>&nbsp;</th>
                                    <th>Name</th>
                                    <th>Regional Country</th>
                                    <th>Address</th>
                                    <th>Projects</th>
                                </tr>
                            </thead>
                            <tbody>
                                <tr data-ng-repeat="client in clients | orderBy:Name" class="repeat-animation">
                                    <td><img data-ng-src="Content/images/{{client.Name | lowercase}}.png" class="cardImage" alt="Client Image" /></td>
                                    <td>{{client.Name}}</td>
                                    <td>{{client.RegionalCountry}}</td>
                                    <td>{{client.Address}}</td>
                                    <td>
                                        <a href="#/clients" class="btn-link">
                                            {{ client.ProjectCount }}
                                            <span data-ng-pluralize count="client.ProjectCount"
                                                  when="{'1': 'Project','other': 'Projects'}">
                                            </span>
                                        </a>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
        <div class="container">
            <div class="row show-hide-animation" data-ng-show="filteredclients.length == 0">
                <div class="col-span-12">
                    <h4>No clients found</h4>
                </div>
            </div>
        </div>
        <div class="row show-hide-animation" data-ng-show="clients.length > 0">
            <div class="col-md-12">
                <div data-pagination
                     data-on-select-page="pageChanged(page)"
                     data-total-items="totalRecords"
                     data-page="currentPage"
                     data-items-per-page="pageSize"
                     data-boundary-links="true"
                     class="pagination-sm"></div>
            </div>
        </div>
        <br /><br /><br />
    </div>
</div>

Step 15:
You need to add the style.css as your own to show the page perfect looking.

Now we are done and ready to use the client application. It's time to run both application and test it.

By the help of visual studio we could run both application at a time by following the instruction.
  1. Right click on the solution and click Properties.
  2. From the left menu select "Startup Project"
  3. On the right side select "Multiple startup projects"
  4. On action tab select "Start" for both projects. You could do this by the help of below image



Now it's time to play with the applications.
Hopefully you enjoyed the post.

Any feedback or comments would be appreciable,  if there is a better way or modified way to implement this.

A Deep Dive into Computed Columns in Entity Framework Core

Entity Framework Core (EF Core) is a popular Object-Relational Mapping (ORM) framework that simplifies database access for .NET applications...