Skip to main content

.Net5 Blazor WebAssembly CRUD Operation Sample For Beginners

In this article, we will explore CRUD operations in .Net5 Blazor WebAssembly application. This article targeting an audience like beginners of Blazor WebAssebly. 

Create A .Net5 Blazor WebAssembly:

Visual Studio users should have the latest version of 2019VS(Version 16.8.*) to build the .Net5 application. From Visual Studio it is pretty simple to create a Blazor WebAssebly application since VS provides users with a nice GUI for interaction.

One other option to create an application is with .Net CLI commands. So one of the best IDE for .Net CLI developers is Visual Studio Code Editor.
.Net CLI Command To Create Blazor WebAssembly Project:
dotnet new blazorwasm -n your_project_name

Rest API:

In the blazor webassembly application, displaying data, storing or updating data, or removing data is carried out by Rest API. So for in our demo application, we will consume a free rest API like 'https://jsonplaceholder.typicode.com/posts'. But there are limitations with these free rest API's they won't support creating or deleting data. So in our demo for creating, update and delete operations we are going to pretend like we really calling API. 

If you have knowledge on creating rest API, then it will nice be to create a sample API with all CRUD operations and then use that API in the blazor webassembly application.

Different HttpClient Techniques:

In this demo, we are going to use the 'Type Client' technique. The 'Type Client' technique means creating a specific class to an API domain, in that class we will implement all API calls logic like fetching, updating, and deleting. So each API domain will have an individual POCO class in 'Type Client'.

Install Http Extension Packege:

To use the 'Type Client' technique we need to register our POCO class in the start file using the 'AddHttpClient' service. The 'AddHttpClient' service bundled with the HTTP extension library, so need to install the library mention below.
Package Manager Command:
Install-Package Microsoft.Extensions.Http -Version 5.0.0
.Net CLI Command:
dotnet add package Microsoft.Extensions.Http --version 5.0.0

Create API Response Model:

To use API JSON response into our blazor webassembly application, we have to deserialize the JSON string response to the C# POCO class object. So we have to create an API response model. So let's create a folder like 'Models' and then add a new class like 'Post.cs'.
Models/Post.cs:
namespace dotnet5.bwasm.crud.Models
{
    public class Post
    {
        public int Id { get; set; }
        public string Title { get; set; }
        public string Body { get; set; }
    }
}
Register 'Models' folder namespace in '_Import.razor'. By registering namespaces in  '_Imports.razor' we can directly access any class by its name into the razor component. If we don't register the namespace in '_Imports.razor', then we have to call any class with the fully qualified name(means along with namespace) into the razor components.
_Imports.razor:
@using dotnet5.bwasm.crud.Models

Create 'Type Client' POCO Class To Implement API Calls:

As we have already decided to use the 'Type Client' technique of the HttpClient. So let's create a folder like 'APIClients' and then add a new class like 'JsonPlaceHolderClient.cs'.
APIClients/JsonPlaceHolderClient.cs:
using System.Collections.Generic;
using System.Net.Http;
using System.Net.Http.Json;
using System.Threading.Tasks;
using dotnet5.bwasm.crud.Models;

namespace dotnet5.bwasm.crud.ApiClients
{
    public class JsonPlaceHolderClient
    {
        private HttpClient _httpClient;
        public JsonPlaceHolderClient(HttpClient httpClient)
        {
            _httpClient = httpClient;
        }

        public async Task<List<Post>> GetAllPost()
        {
            return await _httpClient.GetFromJsonAsync<List<Post>>("/posts");
        }
    }
}
  • (Line: 12) Injecting the 'HttpClient' object into the 'JsonPlaceHolderClient'. This injection is possible on registering our 'Type Client'(JsonPlaceHolderClient) into the 'AddHttpClient' service extension method in the Program file. While registering our 'Type Client'(JsonPlaceHolderClient) we will specify some default configurations like domain, default headers, connection timeout, etc. So framework while injecting 'HttpClient' into the 'Type Client'(JsonPlaceHolderClient) class it will bundle all the configuration that registered into the 'HttpClient' object. We will register our 'Type Client'(JsonPlaceHolderClient) in the upcoming step.
  • (Line: 17-20) A method that fetches a collection of 'Posts'.
  • (Line: 19) An asynchronous API call to the "posts" endpoint. The domain for the API automatically appended by the 'HttpClient'. Because 'HttpClient' object contains all our default configurations registered in the 'Program.cs' file.
  • The 'GetFrormJsonAsync' method triggers the API call. On receiving JSON string response, our method will automatically deserialize our response to collection 'Posts' of c# object type.
Register 'ApiClients' folder namespace in '_Imports.razor'.
_Imports.razor:
@using dotnet5.bwasm.crud.ApiClients

Register JsonPlaceHolderClient In Progra.cs File:

Using 'AddHttpClient' extension method we have to register our JsonPlaceHolderClient in Program.cs file. It helps to inject the 'HttpClient' object into the 'JsonPlaceHolder' file by the HttpClientFactory implicitly.
Program.cs:
builder.Services.AddHttpClient<JsonPlaceHolderClient>(client => {
	client.BaseAddress = new Uri("https://jsonplaceholder.typicode.com");
});
  • The configured base domain of the rest API.

Read Operation In Blazor Component:

Let's understand how to read or fetch data into the blazor component in the blazor webassembly application. So first clean up the existing code in 'Pages/Index.razor', because in our sample we are going to implement all our CRUD operations in this file.
Pages/Index.razor:(HTML Part)
@page "/"
@inject JsonPlaceHolderClient _jsonPlaceHolderClient;

<h1>All Posts</h1>
<table class="table table-striped">
    <thead>
        <tr>
            <th scope="col">Id</th>
            <th scope="col">Title</th>
            <th scope="col">Description</th>
        </tr>
    </thead>
    <tbody>
        @foreach (var post in allposts)
        {
            <tr>
                <td>@post.Id</td>
                <td>@post.Title</td>
                <td>@post.Body</td>
            </tr>
        }
    </tbody>
</table>
  • (Line: 1) Razor syntax to define the route for the blazor page component can be done by the '@page' directive.
  • (Line: 2) Here 'JsonPalceHolderClient' instance injected using '@inject' directive.
  • Rendering the 'Posts' data into the table for display. Here 'allposts' variable contains the data fetched from the API.
Pages/Index.razor:(Code Part)
@code{
    private List<Post> allposts = new List<Post>();

    protected override async Task OnInitializedAsync()
    {
        allposts = await _jsonPlaceHolderClient.GetAllPost();
    }
}
  • (Line: 2) The 'allposts' variable holds the data from the API. This variable will be used by Html code to display the content.
  • The 'OnIntializedAsync' method gets invoked on rendering of the blazor component. Since we also need to display the content on the page opens, we will invoke our API in this method.
Run the application, then we can see the output as below.

Post API Call:

We know that our test API "http://jsonplaceholder.typicode.com/posts" doesn't support create or update or delete operations. But we pretend like it will support all those operations and implement the logic so that when we expose ourselves to real application it will be helpful.

In real-time most of the APIs can support the creation and update with a single endpoint, our logic will be implemented by considering this scenario. Let's add  our logic for 'CreateOrUpdatePost' method in 'JsonPlaceHolderClient'.
ApiClients/JsonPlaceHolderClient.cs:
public async Task<Post> CreateOrUpdatePost(Post newPost)
{
	#region  for-real-appliation-development
	// var response = await _httpClient.PostAsJsonAsync<Post>("/create", newPost);
	// return await response.Content.ReadFromJsonAsync<Post>();
	#endregion
	#region  dummy-implementation-for-demo
	await Task.FromResult(0);
	return newPost;
	#endregion
}
  • (Line: 3-6) Here is commented code, because this is the appropriate approach to implement when we have a working endpoint. The 'PostAsJsonAsync<T>' method invokes the save or update endpoint. The type passed to the method 'PostAsJsonAsync' nothing but the type of the payload. Behind the scenes 'PostAsJsonAsync' serializes payload and sends it to the API and captures the 'HttpResponseMessage'. Here from the response, we are trying to read the 'Post' object, but response data can be vary based on API implementation like few API's return the primary key or unique identifier of the record or few API's return full object like above.
  • (Line: 7-10) For demo purposes simply returning the input 'Post' object.

Scripts To Interact With Bootstrap Modal Popup:

For creating a new record or updating a record we will be going to open up the bootstrap modal with form. So to do this we have to write some javascript code as well.

Now we have to create a JS file in which we have to write javascript logic for opening and closing of the bootstrap modal popup. These javascript methods will be invoked by the .net code in upcoming steps. Create a folder 'js' inside of the 'wwwroot' folder and then add a file like 'app.js'
wwwroot/js/app.js:
window.global = {
  openModal: function (popupId) {
    popupId = "#" + popupId;
    $(popupId).modal("show");
  },
  closeModal: function (popupId) {
    popupId = "#" + popupId;
    $(popupId).modal("hide");
  },
};
  • Here we have 2 javascript functions for opening and closing the bootstrap modal. These methods are written like generic, by inputting any modal id can be able to open and close.
Script files like 'app.js', 'jquery.js', 'bootstrap.js' need to be added to the index.html file.
wwwroot/index.html:
<script 
src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" 
crossorigin="anonymous">
</script>
<script 
src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.0-beta2/dist/js/bootstrap.bundle.min.js" integrity="sha384-b5kHyXgcpbZJO/tY9Ul7kGkf1S0CWuKcCD38l8YkeH8z8QjE0GmW1gYU5S9FOnJ0" crossorigin="anonymous">
</script>
<script 
src="js/app.js">
</script>

Create Or Update Operations In Blazor Component:

Now we have to update our component to perform both create and update operations.
Pages/Index.razor:(Html Part)
@page "/"
@inject JsonPlaceHolderClient _jsonPlaceHolderClient;
@inject IJSRuntime _js;

<h1>All Posts</h1>
<button class="btn btn-primary" @onclick='@(e => OpenModal(0,"add"))'>Add Post</button>
<table class="table table-striped">
    <!-- code Hiden for display purpose -->
    <tbody>
        @foreach (var post in allposts)
        {
            <tr>
                <!-- code Hiden for display purpose -->
                <td>
                    <button type="button" class="btn btn-primary"
                        @onclick='@(e => OpenModal(post.Id,"update"))'>Edit</button>
                </td>
            </tr>
        }
    </tbody>
</table>

<!-- Html for Model for for creating or updating 'post' data -->
<div class="modal" tabindex="-1" role="dialog" id="myModal">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">@formTitle</h5>
                <button type="button" class="close" @onclick="(e => CloseModal())" aria-label="Close">
                    <span aria-hidden="true">×</span>
                </button>
            </div>
            <div class="modal-body">
                <div class="form-group">
                    <label for="txtTitle">Title</label>
                    <input type="text" class="form-control" id="txtTitle" @bind="payload.Title">
                </div>
                <div class="form-group">
                    <label for="txtDescription">Description</label>
                    <input type="text" class="form-control" id="txtDescription" @bind="payload.Body">
                </div>
            </div>
            <div class="modal-footer">
                <button type="button" class="btn btn-primary" @onclick="(e => CreateOrUpdatePost())">Save changes</button>
                <button type="button" class="btn btn-secondary" @onclick="(e => CloseModal())">Close</button>
            </div>
        </div>
    </div>
</div>
  • (Line: 3) Injected IJSRuntime, the IJSRuntime will be used to invoke the javascript code from the dotnet code.
  • (Line: 6) Added a button to create a new 'Post'. On clicking the button we are invoking the bootstrap modal by calling the 'OpenModal' method. Here we are returning the method 'OpenModal' as an output for the click event like "(e => OpenModal())". The 'OpenModal' method takes 2 input parameter like 'postId' and 'operationType'. The 'postId' value is '0' then a popup triggered for creating the new record. The 'operationType' value will be 'add' it also defines the operation for adding a new record.
  • (Line: 15-16) Added new column like actions in the table. Here we added an edit button to open the form with the record values to be edited.
  • (Line: 24-49) Html code of bootstrap modal that contains a form to operate on 'Post' data.
  • (Line: 28) The property 'formTitle' will be rendered at the top of the form. On clicking the 'Add' or 'Edit' button content of the 'formTitle' changes
  • (Line: 38-40) Modal created with a cross button to close the popup. Register the click event with a method name like 'CloseModal'.
  • (Line: 36-40) Input fields are decorated with the '@bind' directive to enable the 2-way binding in the blazor webassembly. 
  • (Line: 44) The 'Save Changes' button registered with a click event to a method 'CreateOrUpdatePost'.
  • (Line: 45) The 'Close' button registered with a click event to a method 'CloseModal'.

Pages/Index.razor:(Code Part)

@code{
    private List<Post> allposts = new List<Post>();
    private Post payload = new Post();

    string formTitle = "";
    protected override async Task OnInitializedAsync()
    {
        allposts = await _jsonPlaceHolderClient.GetAllPost();
    }

    private async Task OpenModal(int postId, string operationType)
    {
        if (operationType.ToLower() == "add")
        {
            formTitle = "Add Post";
            payload = new Post();
            await _js.InvokeVoidAsync("global.openModal", "myModal");
        }
        else
        {
            formTitle = "update Post";
            payload = allposts.Where(_ => _.Id == postId).FirstOrDefault();
            await _js.InvokeVoidAsync("global.openModal", "myModal");
        }
    }

    private async Task CloseModal()
    {
        await _js.InvokeVoidAsync("global.closeModal", "myModal");
    }

    private async Task CreateOrUpdatePost()
    {
        if (payload.Id == 0)
        {
            // for adding new record
            var newRecord = await _jsonPlaceHolderClient.CreateOrUpdatePost(payload);

            #region logic-only-for-demo
            int lastRecordId = allposts.OrderByDescending(_ => _.Id).Select(_ => _.Id).FirstOrDefault();
            newRecord.Id = lastRecordId + 1;
            #endregion
            allposts.Insert(0, newRecord);
            await CloseModal();
        }
        else
        {
            var updatedRecord = await _jsonPlaceHolderClient.CreateOrUpdatePost(payload);

            allposts = allposts.Where(_ => _.Id != updatedRecord.Id).ToList();

            allposts.Insert(0, updatedRecord);
            await CloseModal();
        }
    }
}
  • (Line: 3) The 'payload' variable will be used by our bootstrap modal form. This object will be used for editing or creating 'Post'record by capturing the user entered data from the form.
  • (Line: 5) The 'formTitle' variable to display the title of modal form dynamically.
  • (Line: 11-25) Method 'OpenModal' to open the bootstrap modal by clicking the 'Edit' or 'Add' button.
  • (Line: 13-18) This block of logic executes on clicking the 'Add' button.
  • (Line: 16) Assigning empty 'Post' object to the 'payload' variable, so that form fields will be empty on modal opens.
  • (Line: 17&23) Here invoking the javascript code from the dotnet code. The 'InvokeVoidAsyc' method contains two parameters like the first parameter is the name of the javascript function and the second parameter is input values to that javascript function.
  • (Line: 19-24) This block of logic executes on clicking the 'Edit' button.
  • (Line: 22) On clicking the edit button the 'Post' record id is passed as an input parameter to the 'OpenModal' method. So using that post id we have to filter the record that needs to be edited from the 'allposts'(variable that contains all post data). So filtered object will be assigned to the 'payload' variable, then the modal form will be populated with data to edit it.
  • (Line: 27-30) A method that closes the bootstrap modal on clicking the close button.
  • (LIne: 32-55) The 'CreateOrUpdatePost' method contains logic to invoke the API to save or update the record by clicking the 'SaveChanges' button on the bootstrap modal.
  • (Line: 34) Checking condition for adding new 'Post' record.
  • (Line: 37) Invoking our save API call where we pass our 'payload' variable data as input to it.
  • (Line: 39-42) Here it is fake logic because we know that our test API won't support add or update data so for the demo purpose we are incrementing record id manually as pretending like a record is saved in the server.
  • (Line: 43) Now the new record is added at top of collection, so that it will be displayed on the top of the table.
  • (Line: 46-54) This block of code contains the logic, to update the record. Hereafter invoking the save API we removing the existing record from the collection and then inserting the updated record on top of the collection.
Output on clicking the add button.

Output on clicking the edit button.

Delete API Call:

ApiClients/JsonPlaceHolderClient:
public async Task DeletePost(int id)
{
	#region  for-real-application
	// await _httpClient.DeleteAsync($"delete?id={id}");
	#endregion

	#region dummy-implementation-for-demo
	await Task.FromResult(0);
	#endregion
}
  • We know that our test API doesn't support delete API, here we just commented out the actual code. But this commented code will be helpful when we have a working delete endpoint.

Delete Operation In Blazor Component:

We have to add the 'Delete' button in the table like we added the 'Edit' button previously, then we have to register the click event with a method that should contain logic to invoke the delete API and on the success of the delete API  we have to remove the item from the collection of 'Posts' that is stored in variable 'allposts'.
Pages/Import.razor:(Html Part)
<button type="button" class="btn btn-primary"
@onclick='@(e => DeletePost(post.Id))'>Delete</button>   
Pages/Import.razor:(Code Part)
private async Task DeletePost(int id)
{
	await _jsonPlaceHolderClient.DeletePost(id);
	allposts = allposts.Where(_ => _.Id != id).ToList();
}
So that's all about the steps to implement CRUD operation .Net5 blazor webassembly application.

Video Session:

 

Support Me!
Buy Me A Coffee PayPal Me

Wrapping Up:

Hopefully, I think this article delivered some useful information on steps to implement CRUD operations in the .net5 blazor webassembly application. I love to have your feedback, suggestions, and better techniques in the comment section below.

Refer:

Follow Me:

Comments

  1. it would be better with real SQL Server database .InvokeVoidAsync("global.closeModal .. not working and complicated to run

    ReplyDelete
    Replies
    1. Blazor Webassembly dont use database directly. It consumes only Api's. Global.closeModal will work, either clone my repo or check blog again

      Delete

Post a Comment

Popular posts from this blog

Endpoint Routing In Asp.Net Core

How Routing Works In  Core 2.1 And Below Versions?: In Asp.Net Core routing is configured using app.UseRouter() or app.UseMvc() middleware. app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); Here in Dotnet Core version 2.1 or below versions on the execution of route middleware request will be navigated appropriate controller matched to the route. An operation or functionality which is dependent on route URL or route values and that need to be implemented before the execution of route middleware can be done by accessing the route path from the current request context as below app.Use(async (context, next) => { if(context.Request.Path.Value.IndexOf("oldvehicle") != -1) { context.Response.Redirect("vehicle"); } else { await next(); } }); app.UseMvc(routes => { routes.MapRoute( name: "vehicleRoute", template: "vehicle", defaul

Asp.Net Core MVC Form Validation Techniques

Introduction: Form validations in any applications are like assures that a valid data is storing on servers. All programing frameworks have their own individual implementations for form validations. In Dotnet Core MVC application server-side validations carried on by the models with the help of Data Annotations and the client-side validations carried by the plugin jQuery Unobtrusive Validation. jQuery Unobtrusive Validation is a custom library developed by Microsoft based on the popular library  jQuery Validate . In this article, we are going to learn how the model validation and client-side validation works in Asp.Net Core MVC Application with sample examples. Getting Started: Let's create an Asp.Net Core MVC application project using preferred editors like Microsoft Visual Studio or Microsoft Visual Studio Code. Here I'm using Visual Studio. Let's create an MVC controller and name it as 'PersonController.cs' and add an action method as bel

.NET Core MVC Application File Upload To Physical Location With Buffered Technique

Buffering Technique In File Upload: The server will use its Memory(RAM) or Disk Storage to save the files on receiving a file upload request from the client.  Usage of Memory(RAM) or Disk depends on the number of file requests and the size of the file.  Any single buffered file exceeding 64KB is moved from Memory to a temp file on disk.  If an application receives heavy traffic of uploading files there might be a chance of out of Disk or RAM memory which leads to crash application. So this Buffer technique used for small files uploading. In the following article, we create a sample for the file uploading using .NET Core MVC application. Create The .NET Core MVC Project: Let's create a .NET Core MVC project, here for this sample I'm using Visual Studio Code as below.   Check the link to use the Visual Studio Code for .NET Core Application . IFormFile: Microsoft.AspNetCore.Http.IFormFile used for file upload with buffered technique. On uploading files f

Ionic Picker Sample Code In Angular

Introduction: Ionic Picker(ion-picker) is a popup slides up from the bottom of the device screen, which contains rows with selectable column separated items. The main building block of ion-picker as follows: PickerController PickerOptions PickerController: PickerController object helps in creating an ion-picker overlay. create(opts?: Opts): Promise<Overlay> PickerController create method helps in create the picker overlay with the picker options PickerOptions: PickerOptions is a configuration object used by PickerController to display ion-picker. Single Column Ionic Picker: single.item.picker.ts: import { Component } from "@angular/core"; import { PickerController } from "@ionic/angular"; import { PickerOptions } from "@ionic/core"; @Component({ selector: "single-column-picker", templateUrl:"single.item.picker.html" }) export class SingleItemPicker { animals: string[] = ["Tiger&quo

How Response Caching Works In Asp.Net Core

What Is Response Caching?: Response Caching means storing of response output and using stored response until it's under it's the expiration time. Response Caching approach cuts down some requests to the server and also reduces some workload on the server. Response Caching Headers: Response Caching carried out by the few Http based headers information between client and server. Main Response Caching Headers are like below Cache-Control Pragma Vary Cache-Control Header: Cache-Control header is the main header type for the response caching. Cache-Control will be decorated with the following directives. public - this directive indicates any cache may store the response. private - this directive allows to store response with respect to a single user and can't be stored with shared cache stores. max-age - this directive represents a time to hold a response in the cache. no-cache - this directive represents no storing of response and always fetch the fr

GraphQL API Integration In Asp.Net Core Application

Introduction: GraphQL is a query language for your API and a server-side runtime for executing queries by using a type system you define for your data. GraphQL can be integrated into any framework like ASP.NET, Java, NestJs, etc and it isn't tied to any specific database or storage engine and is instead backed by your existing code and data. How GraphQL API Different From Rest API: GraphQL exposes a single end-point or route for the entire application, regardless of its responses or actions. HTTP-POST is the only Http verb recommended by the GraphQL. The client applications (consumers of API) can give instructions to GraphQL API about what type of properties to be returned in the response. Building Blocks Of GraphQL API: The main building blocks of GraphQL API is Schemas and Types.  A 'Schema' in GrpahQL API describes the functionality available to the clients connect to API. Schema mostly consists of GraphQL Object Types, Queries, Mutations, etc. T

ASP.NET Core Web API Versioning

Introduction: An iteration and evolutionary changes of an ASP.NET Core Web API is handled by Versioning. Versioning of an API gives confidence to the clients which consumes API for a long time. Any changes or development of an API will be accessible using the new version and it won't cause issues to the clients consuming the old version of API. When To Use Versioning: Any API response changes. Developing an API by implementing testing levels like 'Alpha', 'Beta', and 'RC' versions before releasing Production. Deprecating an API which means API going to be removed or upgraded by a version within a short period. Versioning Types: Query String Versioning Url Path Versioning Media Type Versioning API Version Nuget: To Configure versioning to AspNet Core Web API Microsoft provided a library(Microsoft.AspNetCore.Mvc.Versioning). So to use the versioning library please install NuGet below.              Install-Package Microsoft.A

.Net Core HttpClient JSON Extension Methods Using System.Net.Http.Json Package

.Net Core 3.0 onwards Microsoft brought up a new package called System.Net.Http.Json. This new package provides JSON extension methods for HttpClient. These JSON extension methods will have a prebuild mechanism for serializing or deserializing response data or payload of HttpClient call. System.Net.Http.Json extension methods that are provided to HttpClient, few of them are mentioned below. GetFromJsonAsync PostAsJsonAsync PutAsJsonAsync ReadFromJsonAsync In this article, we understand System.Net.Http.Json package by implementing the HttpClient samples by with and without JSON extension methods and compare them. Create A .Net Core Web API Sample Application: Let's create a .Net Core sample Web API application, from this application we will consume another Web API by implementing HttpClient calls. We can create a Web API sample application using IDE like Visual Studio 2019(Supports .Net Core 3.0 plus) or  Visual Studio Code . Create A Typed Client: In .Net Core using the Http

Blazor Server CRUD Operations

Introduction: Blazor Server is a web framework to develop server-side single-page applications. Blazor is made up of components with the combinations on C#, Html, CSS.  Blazor Server is production-ready from the .Net Core 3.0.  Blazor Server Working Mechanism: Blazor Server is a very light-weight web development framework.  In Blazor Server, not all code gets downloaded to the client browsers. Blazor Server made of components these components can be a block of code or page with respective navigation.  Blazor server application communicates with the server with a SignalR background connection which is inbuilt functionality. Application click,  form submission, change events, application page navigation every operation is carried out by the SignalR connection by communicating with the server.  Blazor updates the Html DOM very gently on every data update without any overhead. Blazor Server application maintains a nice intelligent tree structure to update the required inform

Blazor WebAssembly Custom Authentication From Scratch

In this article, we are going to explore and implement custom authentication from the scratch. In this sample, we will use JWT authentication for user authentication. Main Building Blocks Of Blazor WebAssembly Authentication: The core concepts of blazor webassembly authentication are: AuthenticationStateProvider Service AuthorizeView Component Task<AuthenticationState> Cascading Property CascadingAuthenticationState Component AuthorizeRouteView Component AuthenticationStateProvider Service - this provider holds the authentication information about the login user. The 'GetAuthenticationStateAsync()' method in the Authentication state provider returns user AuthenticationState. The 'NotifyAuthenticationStateChaged()' to notify the latest user information within the components which using this AuthenticationStateProvider. AuthorizeView Component - displays different content depending on the user authorization state. This component uses the AuthenticationStateProvider