Live Chat Icon For mobile
Live Chat Icon

Blazor FAQ

Find answers for the most frequently asked questions
Expand All Collapse All

Blazor prerendering is a process where web page elements are built and compiled on the server and static HTML is hosted in WebAssembly (client side). When Razor pages load, components are prerendered at the same time. This process improves page loading by making it faster for SPAs (single page applications), which improves search engine optimization.

Follow the steps below to create a prerender Blazor WebAssembly app.

  1. Create a new Blazor WebAssembly application using the .NET CLI.

    dotnet new blazorwasm -o BlazorPrerendering.Client

  2. Add a new empty ASP.NET Core Web App to host the project.

    dotnet new web -o BlazorPrerendering.Server


    The solution should now look like this.


  3. Now, add the WebAssembly (client side) project reference in the host server project file (BlazorPrerendering.Server.csproj) and also include the NuGet package (Microsoft.AspNetCore.Components.WebAssembly.Server) using NuGet Package Manager.

    [BlazorPrerendering.Server.csproj]

     <Project Sdk="Microsoft.NET.Sdk.Web">
     
     . . .
     . . .
     
      <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.Server" Version="3.2.1" />
      </ItemGroup>
     
      <ItemGroup>
        <ProjectReference Include="..\BlazorPrerendering.Client\BlazorPrerendering.Client.csproj" />
      </ItemGroup>
     
     
    </Project>

  4. Configure the host in the host server project Startup.cs file.

    [BlazorPrerendering.Server/Startup.cs]

    namespace BlazorPrerendering.Server
    {
        public class Startup
        {
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddRazorPages();
     
                services.AddSingleton<HttpClient>(sp =>
                {
                    // Get the address that the app is currently running at
                    var server = sp.GetRequiredService<IServer>();
                    var addressFeature = server.Features.Get<IServerAddressesFeature>();
                    string baseAddress = addressFeature.Addresses.First();
                    return new HttpClient { BaseAddress = new Uri(baseAddress) };
                });
            }
           
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    // Call UseDeveloperExceptionPage on the app builder in the Development environment. 
                    app.UseDeveloperExceptionPage();
                    app.UseWebAssemblyDebugging();
                }
                else
                {
                    app.UseExceptionHandler("/Error");
                    app.UseHsts();
                }
     
                app.UseHttpsRedirection();
                // Call UseBlazorFrameworkFiles on the app builder.
                app.UseBlazorFrameworkFiles();
                app.UseStaticFiles();
                app.UseRouting();
     
                // Change the fallback from the index.html file
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapRazorPages();
                    endpoints.MapControllers();
                    endpoints.MapFallbackToPage("/_Host");
                });
            }
     
        }
    }

  5. Now, you need to create a folder called Pages in the root of the host server project and create a razor page file called _Host.cshtml with the following code.

    [BlazorPrerendering.Server/Pages/_Host.cshtml]

     @page "/"
    @namespace BlazorPrerendering.Server.Pages
    // Nneed to enable Tag Helpers on the Razor Page
    @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
     
    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
        <title>Prerendering client-side Blazor</title>
        <base href="~/" />
        <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
        <link href="css/app.css" rel="stylesheet" />
        <link href="BlazorPrerendering.Client.styles.css" rel="stylesheet" />
     
    </head>
    <body>
        <component type="typeof(BlazorPrerendering.Client.App)" render-mode="WebAssemblyPrerendered" />
     
        <div id="blazor-error-ui">
            An unhandled error has occurred.
            <a href="" class="reload">Reload</a>
            <a class="dismiss">🗙</a>
        </div>
     
        <script src="_framework/blazor.webassembly.js"></script>
    </body>
    </html>

  6. Now, remove the default static wwwroot/index.html file from the Blazor WebAssembly client project.

  7. Delete the following line in Program.cs in the client project.

    [BlazorPrerendering.Client /Program.cs]

    builder.RootComponents.Add<App>("#app"); 


    Now run the application, and you will find the prerendered Blazor WebAssembly app.

Refer to “Prerender and integrate ASP.NET Core Razor components” for more details.

Permalink

In the following example, the cookie consent banner temple will display to notify you to accept cookies. Follow the below steps to create a consent cookie in Blazor.

1. Configure the HttpContextAccessor and CookiePolicyOptions to the startup file to create a consent cookie.

[Startup.cs]

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;

public class Startup
    {
       . . .
       . . .
       public void ConfigureServices(IServiceCollection services)
        {
           . . .
                        .   .   .
                         services.Configure<CookiePolicyOptions>(options =>
            {
                options.CheckConsentNeeded = context => true;
                options.MinimumSameSitePolicy = SameSiteMode.None;
            });
            services.AddHttpContextAccessor();
        }
               public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
          . . .
                      .   .   .
                       app.UseCookiePolicy();
         }
           }

2. Now, add the Cookie consent banner template as a Razor component under the Shared folder.

[ConsentCookie.razor]

@using Microsoft.AspNetCore.Http.Features
@using Microsoft.AspNetCore.Http

@inject IHttpContextAccessor Http
@inject IJSRuntime JSRuntime


@if (showBanner)
{
    <div id="cookieConsent" class="alert alert-info alert-dismissible fade show" role="alert">
        Consent to set cookies.
        <button type="button" class="accept-policy close" data-dismiss="alert" aria-label="Close" data-cookie-string="@cookieString" @onclick="AcceptMessage">
            Accept Cookie
        </button>
    </div>
}
@code {
    ITrackingConsentFeature consentFeature;
    bool showBanner;
    string cookieString;

    protected override void OnInitialized()
    {
        consentFeature = Http.HttpContext.Features.Get<ITrackingConsentFeature>();
        showBanner = !consentFeature?.CanTrack ?? false;
        cookieString = consentFeature?.CreateConsentCookie();
    }

    private void AcceptMessage()
    {
        // JsInterop call to store the consent cookies.
        JSRuntime.InvokeVoidAsync("CookieFunction.acceptMessage", cookieString);
    }
}

3. Add the JavaScript function in the _Host.cshtml file to store the cookie.

[_Host.cshtml]

<body>
      . . .
      . . .

      <script>
        window.CookieFunction = {
            acceptMessage: function (cookieString) {
                document.cookie = cookieString;
            }
        };    
   </script>
</body>

4. Refer to the cookie consent banner template Razor component in the MainLayout.razor file.

[MainLayout.razor]

<div class="page">
    . . .
    . . .

    <div class="main">
        . . .
        . . .
        <ConsentCookie />

        <div class="content px-4">
            @Body
        </div>
    </div>
</div>

5. Run the application, and you will find the consent cookie banner.

6. Now, click the Accept cookie button to store the cookie in the browser.

Refer to “How to set consent cookie in Blazor Server” for more details.

Permalink

Blazor doesn’t manipulate the DOM directly at C# side. You cancall the JavaScript method by using JavaScript Interop to get an element by ID or class.

  • The getElementsByClassName() method returns a collection of all elements in the document with the specified class names.
  • The getElementById() method returns a collection of all elements in the document with the specified ID names.

[Index.razor]

@page "/"
@inject IJSRuntime JsRuntime

<h1 id="headingElement">Hello, world!</h1>

<p class="para-element">Welcome to your new app.</p>

@code {
    protected override async void OnAfterRender(bool firstRender)
    {
        await JsRuntime.InvokeVoidAsync("elementId");
    }
}

[_Host.cshtml]

<body>
      . . .
      . . .

      <script>
        function elementId() {
            // Get element with the specified ID name
            var idValue = document.getElementById("headingElement");
            console.log(idValue.innerHTML);
            // Get element with the specified Class name
            var classValue = document.getElementsByClassName("para-element");
            console.log(classValue[0].innerHTML);
        }
    </script>
</body>

Refer to “Call JavaScript functions from .NET methods in ASP.NET Core Blazor” for more details.

Permalink

Configure the logger in the builder in the Program.Main configuration file. Add a package reference for Microsoft.Extensions.Logging.Configuration to the Blazor app’s project file using the NuGet package manager.

Now, add the namespace as Microsoft.Extensions.Logging to Program.cs and add the builder logging configuration. This configuration will prevent the logging info in the browser console.

[Program.cs]

using Microsoft.Extensions.Logging;
. . .
. . .
public class Program
    {
        public static async Task Main(string[] args)
        {
            . . .
            . . .
         Builder.Logging.AddConfiguration(builder.Configuration.GetSection("Logging"));
         
        }
    }

Refer to “Logging configuration” for more details.

Permalink

In Blazor, you can call a JavaScript method using JavaScript interop to scroll the page to the top position.

In the following code, the button event triggers when the button is clicked and scrolls to the page top.

[Index.razor]

@page "/"
@inject IJSRuntime JsRuntime

<div style="background-color:lightgrey;padding:60px 60px 1000px">
    <h2>Blazor App</h2>
    This example demonstrates how to scroll to the top based on the button click event.<br />
    Scroll down and click the button; it scrolls to the top position.
</div>
<div><br />
<button @onclick="OnButtonClick" class="btn btn-primary">Click Button</button>
</div>

@code {

    private async void OnButtonClick()
    {
        await JsRuntime.InvokeVoidAsync("OnScrollEvent");
    }
}

[_Host.cshtml]

<body>
. . .
. . .
<script>
        // When the user clicks the button, the page scrolls to the top
        function OnScrollEvent() {
            document.documentElement.scrollTop = 0;
        }
    </script>
</body>

Permalink

Follow the below steps to convert an existing Blazor Server project into a Blazor WebAssembly project.

Prerequisites:

  • .NET Core 3.1/.NET 5.0
  • Visual Studio 2019

1. Open the existing Blazor Server app project file (.csproj) and add the Blazor WebAssembly SDK and package references.

[BlazorServerApp.csproj]

<Project Sdk="Microsoft.NET.Sdk.BlazorWebAssembly">
   . . .
   . . .

   <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="5.0.4" />
    <PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="5.0.4" PrivateAssets="all" />
    <PackageReference Include="System.Net.Http.Json" Version="5.0.0" />
  </ItemGroup>

</Project>

2. Delete the Startup.cs file configuration in the existing Blazor Server app and add the required WebAssembly configurations to the Program.cs file. Add the following code for WebAssembly configuration.

[Program.cs]

using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace BlazorServerApp
{
    public class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("#app");

            builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

            await builder.Build().RunAsync();
        }
    }
}

3. Now add the below namespace to your converting application in the _Import.razor file.

[_Import.razor]

@using System.Net.Http.Json
@using Microsoft.AspNetCore.Components.WebAssembly.Http

4. Delete the _Host.cshtml, Error.cshtml, and Error.cshtm.cs files under the Pages folder and create an index.html file and add the below code snippet under wwwroot/index.html file.

[index.html]

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>{{Your_Application_Name}}</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/site.css" rel="stylesheet" />
    <link href="{{Your_Application_Name}}.styles.css" rel="stylesheet" />
</head>

<body>
    <div id="app">Loading...</div>

    <div id="blazor-error-ui">
        An unhandled error has occurred.
        <a href="" class="reload">Reload</a>
        <a class="dismiss">🗙</a>
    </div>
    <script src="_framework/blazor.webassembly.js"></script>
</body>

</html>

5. Now, run the application. The existing Blazor Server project is now converted into a Blazor WebAssembly project.

Permalink

In Blazor, you can call a JavaScript method using JavaScript interop to copy the input element text to the clipboard.

In the following code, the text entered into the text box will be copied by clicking the button, and it will be displayed in the alert box.

[Index.razor]

@page "/"
@inject IJSRuntime JSRuntime

<div class="form-inline">
    <input id="form-control" type="text" value="Hello World" />
    <button type="button" class="btn btn-primary" @onclick="CopyTextToClipboard">Copy</button>
</div>

@code {
    private async Task CopyTextToClipboard()
    {
        await JSRuntime.InvokeVoidAsync("copyClipboard");
    }
}

[_Host.cshtml]

<body>
. . .
.    .   .
<script>
        function copyClipboard() {
            /* Get the text field */
            var copyText = document.getElementById("form-control");
            /* Select the text field */
            copyText.select();
            /* Copy the text inside the text field */
            document.execCommand("copy");
            /* Alert the copied text */
            alert("Copied the text: " + copyText.value);
        }
    </script>
</body>
Permalink

As opposed to how session cookies work, when opening a page in a new tab or window, a new session occurs with the browsing context. To access the browser sessionStorage in Blazor apps, write custom

code or use a third-party package. The accessed data can be stored in localStorage and sessionStorage. Know that localStorage is scoped to the user’s browser. If the user reloads the page or closes and reopens the browser, the state persists. Session storage is similar to local storage, but data in the session storage will be cleared after the session.

Install the Blazored.SessionStorage Nuget package in the NuGet package manager to store the session data in Blazor. Add the Blazored SessionStorage configuration to the WebAssembly app.

[Program.cs]

using Blazored.SessionStorage;
. . .
. . .

public class Program
    {
        public static async Task Main(string[] args)
        {
            . . .
            . . .

            builder.Services.AddBlazoredSessionStorage();
            
        }
    }

[Index.razor]

@page "/"
@inject Blazored.SessionStorage.ISessionStorageService sessionStorage

<h2>@Name</h2>
<button class="btn btn-primary" @onclick="Clear">Clear Session</button>
@code {
    public string Name;
    protected override async Task OnInitializedAsync()
    {
        await sessionStorage.SetItemAsync("ID", "20019");
        await sessionStorage.SetItemAsync("Name", "John Smith");
        Name = "ID: " + await sessionStorage.GetItemAsync<string>("ID") + "Name : " + await sessionStorage.GetItemAsync<string>("Name");
    }
    public async void Clear()
    {
        //this will clear the session data
        await sessionStorage.ClearAsync();
    }
}

Refer to the GitHub SessionStorage repository for more details.

Permalink

RenderFragment is a delegate that renders a UI segment. So, it does not have an Empty state. It can be null, which is equivalent to empty in the sense that it will produce no rendered output. In the following example, see that the RenderFragments are in a null state or contain a value.

@if (childContent != null) 
{ 
    <p>@childContent</p> 
} 
else 
{ 
    <p>RenderFragment is null</p> 
} 
  
<button class="btn btn-primary" @onclick="OnButtonClick">Click</button> @*RenderFragment is null by default, click the button to update the RenderFragment*@ 
  
@code { 
    private string textContent = "Welcome to your new Blazor app."; 
    private RenderFragment childContent { get; set; } 
     
    private void OnButtonClick() 
    { 
        childContent = BuildRenderTree => BuildRenderTree.AddContent(1, textContent); 
    } 
} 

Refer to the Stack Overflow article “Check if RenderFragment is empty” for more details.

Permalink

An <iframe> tag is known as an inline frame or frame within a frame. It’s an HTML element that allows documents to be embedded within the current page. The following example illustrates how to embed a URL inside an iframe in the Blazor app.

[Index.razor]

@page "/" 

<iframe width="560" height="315" src="https://blazor.net" frameborder="0" allowfullscreen></iframe>
Permalink

Blazor virtualization is a technique for limiting UI rendering to just the parts that are currently visible. It improves the perceived performance of component rendering using the Blazor framework’s built-in virtualization support with the virtualize component. When you are using a long list-item component with a loop, you can use virtualization for better performance.

Use the Virtualize component when:

  • A set of data items in a loop needs to be rendered.
  • Many items can’t be seen when scrolling.
  • Items to be rendered are equal in size.

Prerequisites:

  • .NET 5.0 and above.
  • Visual Studio 2019 Preview 3 (v16.8) or greater.

Follow the below example to achieve this.

[Index.razor]

@page "/"

<Virtualize Items="employees" Context="employee">
    <tr>
        <td>@employee.EmployeeId</td>
        <td>@employee.Salary</td>
    </tr>
</Virtualize>

@code {

    private List<Employee> employees;

    protected override async Task OnInitializedAsync()
    {
        employees = await EmployeeDetails();
    }

    private async Task<List<Employee>> EmployeeDetails()
    {
        List<Employee> empList = new List<Employee>();

        for (int i = 1; i <= 30; i++)
        {
            var emp = new Employee()
            {
                EmployeeId = $"EmpID - {i}",
                Salary = $"Salary - {i * 100}",
            };

            empList.Add(emp);
        }
        return await Task.FromResult(empList);
    }

    public class Employee
    {
        public string EmployeeId { get; set; }
        public string Salary { get; set; }
    }
}

Refer to “ASP.NET Core Blazor component virtualization” for more details.

Permalink

You can read static or local files by creating HttpClient Get calls. The GetStringAsync method sends a request to the specific URI and returns the response body as a string in an async operation.

@inject HttpClient Http

@code {

    protected override async Task OnInitializedAsync()
    {
        var content = await Http.GetStringAsync(request Uri);

    }
}

Please refer to “HttpClient Class” for more details.

Permalink

RenderFragment is used to render components or content at run time in Blazor. The RenderFragment class allows you to create the required content or component in a dynamic manner at runtime. In the following code example, the content is created at runtime on OnInitialized.

[Index.razor]

@page "/"

@childContent

@code {
    private string textContent = "Welcome to your new Blazor app.";
    private RenderFragment childContent { get; set; }

    private RenderFragment AddContent() => builder =>
    {
        builder.AddContent(1, textContent);
    };

    protected override void OnInitialized()
    {
        childContent = AddContent();
    }
}

Refer to ASP.NET Core Blazor templated components” for more details.

Permalink

To localize the text in a Blazor WebAssembly (client-side) app, follow these steps:

1. Create a Blazor WebAssembly project and add the Microsoft.Extensions.Localization NuGet package using NuGet Package Manager.

2. Add the culture resource files in the Shared/ResourceFiles folder and add a drop-down menu to switch between localized text.

[CultureDropDown.razor]

@using  System.Globalization
@inject IJSRuntime JSRuntime
@inject NavigationManager UrlHelpers

<strong>Culture:</strong>
<select class="form.control" @bind="Culture" style="width: 140px; margin-left: 10px;">
    @foreach (var culture in supportedCultures)
    {
        <option value="@culture">@culture.DisplayName</option>
    }
</select>

@code
{
    CultureInfo[] supportedCultures = new[]
    {
        new CultureInfo("en-US"),
        new CultureInfo("es-ES"),
        new CultureInfo("de")
    };

    CultureInfo Culture
    {
        get => CultureInfo.CurrentCulture;
        set
        {
            if (CultureInfo.CurrentCulture != value)
            {
                var jsInvoke = (IJSInProcessRuntime)JSRuntime;
                jsInvoke.InvokeVoid("blazorCulture.set", value.Name);

                UrlHelpers.NavigateTo(UrlHelpers.Uri, true);
            }
        }
    }
}

[MainLayout.razor]

<div class="top-row px-4">
      <CultureDropDown />
      . . .
 </div>

3. Now add the localization configuration and get the current locale’s culture using JSInterop, which is stored in browser window’s local storage.

[Program.cs]

…
using Microsoft.JSInterop;
using System.Threading.Tasks;

namespace BlazorLocaleWASM
{
  public class Program
  {
     public static async Task Main(string[] args)
     {
        …
        …
                builder.Services.AddLocalization();
                var host = builder.Build();
        var jsInterop = host.Services.GetRequiredService<IJSRuntime>();
        var result = await jsInterop.InvokeAsync<string>("blazorCulture.get");
        if (result != null)
        {
          var culture = new CultureInfo(result);
          CultureInfo.DefaultThreadCurrentCulture = culture;
          CultureInfo.DefaultThreadCurrentUICulture = culture;
        }

        await host.RunAsync();
    }
  }
}

[index.html]

<html>

<head>
    . . .
    . . .
</head>

<body>
  ...
     . . .
<script>
        window.blazorCulture = {
            get: () => window.localStorage['BlazorCulture'],
            set: (value) => window.localStorage['BlazorCulture'] = value
        };
    </script>
</body>

</html>

4. Add the text/content for localization in the Index.razor file.

[Index.Razor]

@page "/"
@using BlazorLocaleWASM.Shared.ResourceFiles
@inject Microsoft.Extensions.Localization.IStringLocalizer<Resource> Locale

<h1>@Locale["Hello world"]</h1>

@Locale["Welcome to your new app"]

<SurveyPrompt Title="How is Blazor working for you?" />

5. By default, Blazor WebAssembly carries minimal globalization resources required to display values, such as dates and currency, in the user’s culture. Applications that must support dynamically changing the culture should configure BlazorWebAssemblyLoadAllGlobalizationData in the project file.

[Project file]

<PropertyGroup>        <BlazorWebAssemblyLoadAllGlobalizationData>true</BlazorWebAssemblyLoadAllGlobalizationData>
</PropertyGroup>

6. Run the application.

You can download the reference sample here.

Please refer to this link for more information.

Permalink

Follow these steps to create a Blazor WebAssembly (client-side) application using a command-line interface (CLI).

  1. Create a Blazor WebAssembly App in CLI

    Open a command prompt where you want your project to be located and run the following command.

    dotnet new blazorwasm -o BlazorWebAssemblyApp

    Blazor WASM CLI

  2. Navigate to Blazor WebAssembly App

    Run the cd BlazorWebAssemblyApp command to navigate to the BlazorWebAssemblyApp folder.

  3. Run the application.

    The dotnet run command runs the application. See the following output in the default browser.

    wasm cli host

Note: If you have installed multiple SDK versions and need a specific framework version (e.g., net5.0, netcoreapp3.1) project, then add the -f flag to the dotnet new blazorwasm command. Refer here for the available flag options.

Permalink

Follow these steps to create a Blazor Server application using a command-line interface (CLI).

  1. Create a Blazor Server App in CLI

    Open a command prompt where you want your project to be located and run the following command.

    dotnet new blazorserver -o BlazorServerApp

    blazorserver cli

  2. Navigate to Blazor Server App

    Run the cd BlazorServerApp command to navigate to the BlazorServerApp folder.

  3. Run the apllication.

    The dotnet run command runs the application. See the following output in the default browser.

    server-cli-output

Refer to this documentation for more details.

Permalink

Follow the step-by-step procedure below to create a Blazor Server Application in Visual Studio 2019.

  1. Download and install Visual Studio 2019

    Download and install the latest version of Visual Studio 2019 with the ASP.NET and web development workload.

  2. Create a new project

    Open Visual Studio 2019 and click Create a new project . create new project

  3. Select Blazor app from the template

    Select Blazor App from the template list and click the Next button.
    blazor template

  4. Configuring the project

    The project configuration window will pop up. Click the Create button to create a new project with the default project configuration.
    Blazor server configure

  5. Choose Blazor Server App

    Select a target framework based on your requirement, choose the Blazor Server App from the dashboard, and then click Create to create a new Blazor Server application.

    Blazor server template

  6. Blazor Server App structure

    Now the Blazor Server App is created, and the structure look like the following image.
    Server structure

  7. Run the application.

    Press Ctrl + F5 to run the application and find the output in default browser.
    server output

Refer to this link for more details.

Permalink

Follow the step-by-step procedure below to create a Blazor WebAssembly (client-side) application in Visual Studio 2019.

  1. Download and install Visual Studio 2019

    Download and install the latest version of Visual Studio 2019 with the ASP.NET and web development workload.

  2. Create a new project

    Open Visual Studio 2019 and select Create a new project .
    create new project

  3. Select Blazor app from the template

    Select Blazor App from the template list and click the Next. blazor template

  4. Configuring the project

    The project configuration window will pop up. Click Create button to create a new project with the default project configuration.
    Blazor server configure

  5. Choose Blazor WebAssembly App

    Select a target framework based on your requirements, choose Blazor WebAssembly App from the dashboard, and then click Create to create a new Blazor WebAssembly application.

    blazor wasm template

  6. Blazor WebAssembly App structure

    Now the Blazor WebAssemblyApp is created, and the structure look like in the below image.
    wasm structure

  7. Run the application.

    Press ctrl + F5 to run the application and see the below output in default browser.
    wasm output

Refer to this link for more details.

Permalink

Data annotation localization in Blazor server-side and WebAssembly (client-side) apps is achieved by referencing the Resource class localized string. Follow these steps to achieve this:

  1. Add the required localized error messages to the Resource file in the Resource folder.
  2. In the validation attribute, set the ErrorMessageResourceType as typeof(Resource).
  3. Assign the required validation message to the ErrorMessageResourceName property.

[Index.razor]

@page "/"
@using {{ApplicationName}}.Resource
@using System.ComponentModel.DataAnnotations;

<EditForm Model="@_employee" OnValidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <InputText id="name" @bind-Value="_employee.Name" />
    <button type="submit">Submit</button>
</EditForm>

@code {
    public class Employee
    {
        [Required(ErrorMessageResourceName = "RequiredError", ErrorMessageResourceType = typeof(Resource))]
        [StringLength(5, ErrorMessageResourceName = "LengthError", ErrorMessageResourceType = typeof(Resource))]
        public string Name { get; set; }
    }

    private Employee _employee = new Employee();

    private void HandleValidSubmit()
    {
        Console.WriteLine("OnValidSubmit");
    }
}

Please refer to this link for more details.

Permalink

To use jQuery UI components in a Blazor application, follow these steps:

  1. Add jQuery reference to host the page

    Add jQuery and its UI component script and style references in the ~/_Host.cshtml file.

  2. Initialize the jQuery component

    Initialize the jQuery components in the OnAfterRender lifecycle method in your Blazor application by using the JavaScript Interop’s InvokeVoidAsync method.

Refer to the following code samples.

[_Host.cshtml]

….
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<script src="https://code.jquery.com/jquery-1.12.4.js"></script>
<script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
<script src="~/script.js"></script>
….

[Index.razor]

@page "/"
@inject IJSRuntime jsRuntime

    <div id="top">
        <a href="#section1">Go Section 1</a>
        <a href="#section2">Go Section 2</a>
        <a href="#section3">Go Section 3</a>
    </div><br>
    <div id="section1">
        In the web project, pagination is a very important part where huge numbers of records are listed from the
        database. In that case, Ajax pagination is a preferable way because it will help to improve the User
        Interface
        of your website. You'll easily be able to implement the Ajax pagination with our PHP Pagination class.
        Pagination class helps to generate the pagination links and get the records from the database using Ajax.In
        the
        web project, pagination is a very important part where huge numbers of records are listed from the database.
        In
        that case, Ajax pagination is a preferable way because it will help to improve the User Interface of your
        website. You'll easily be able to implement the Ajax pagination with our PHP Pagination class. Pagination
        class
        helps to generate the pagination links and get the records from the database using Ajax.
    </div>
    <br /><br />
    <div id="section2">
        <a href="#top">BackToTop</a><br />
        In the web project, pagination is a very important part where huge numbers of records are listed from the
        database. In that case, Ajax pagination is a preferable way because it will help to improve the User
        Interface
        of your website. You'll easily be able to implement the Ajax pagination with our PHP Pagination class.
        Pagination class helps to generate the pagination links and get the records from the database using Ajax.In
        the
        web project, pagination is a very important part where huge numbers of records are listed from the database.
        In
        that case, Ajax pagination is a preferable way because it will help to improve the User Interface of your
        website. You'll easily be able to implement the Ajax pagination with our PHP Pagination class. Pagination
        class
        helps to generate the pagination links and get the records from the database using Ajax.
    </div>
    <br /><br />
    <div id="section3">
        <a href="#top">BackToTop</a><br />
        In the web project, pagination is a very important part where huge numbers of records are listed from the database. In that case, Ajax pagination is a preferable way because it will help to improve the User Interface of your website. You'll easily be able to implement the Ajax pagination with our PHP Pagination class.

Pagination class helps to generate the pagination links and get the records from the database using Ajax. In the
        web project, pagination is a very important part where huge numbers of records are listed from the database.
        In
        that case, Ajax pagination is a preferable way because it will help to improve the User Interface of your website. You'll easily be able to implement the Ajax pagination with our PHP Pagination class. Pagination
        class
        helps to generate the pagination links and get the records from the database using Ajax.
    </div>


@code {
    protected override async void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            await jsRuntime.InvokeVoidAsync("renderjQuery");
        }
        base.OnAfterRender(firstRender);
    }
}

[script.js]

function renderjQuery() {
    $('a[href*=\\#]:not([href=\\#])').on('click', function () {
        var target = $(this.hash);
        target = target.length ? target : $('[name=' + this.hash.substr(1) + ']');
        if (target) {
            $('html,body').animate({
                scrollTop: target.offset().top
            }, 1000);
            return false;
        }
    });
}

For more information on this topic, check this link.

Permalink

DateTime.Now.ToShortDateString() and DateTime.Now.ToLongDateString() are methods that return the current culture date format. The string returned by the ToShortDateString and ToLongDateString methods are culture-sensitive. It reflects the pattern defined by the current culture’s date format. You can get the current culture date format by using either of the following methods.

<h2>@DateTime.Now.ToShortDateString()</h2>

or

<h2>@DateTime.Now.ToLongDateString()</h2>

Refer to this link for more details.

Permalink

You can customize the loading text in a Blazor WebAssembly application by editing the tag for target framework version 3.* or the
tag for target framework version 5.* in the index.html page. In the following example, I have customized the loading text while loading.

[index.html] for target framework version 3.*

<body>
    <app>
        <div style="position:absolute; top:30vh; width:100%; text-align:center">
            <h1> Blazor WASM Application</h1>
            <p>The application is loading...</p>
        </div>
    </app>
    . . .
    . . .
</body>

[index.html] for target framework version 5.*

<body>
    <div id="app">
        <div style="position:absolute; top:30vh; width:100%; text-align:center">
            <h1> Blazor WASM Application </h1>
            <p>The application is loading...</p>
        </div>
    </div>
    . . .
    . . .
</body>

Refer to this link for more details.

Permalink

In the following example, LoadingScreen will display a loading message while data is loaded asynchronously. Once the data has been loaded, it replaces the loading message with the actual content.

[LoadingScreen.razor]

@if (contentLoaded)
{
    @ChildContent
}
else
{
     <div style="position:absolute; top:30vh; width:100%; text-align:center">
         <h3>Blazor Server Application</h3>
         <p>The application is loading...</p>
     </div>
}

@code {

    bool contentLoaded;

    [Parameter]
    public RenderFragment ChildContent { get; set; }

    protected override async Task OnInitializedAsync()
    {
        await Task.Delay(4000);
        contentLoaded = true;
    }
}

Wrap the Router in the LoadingScreen to show the loading screen in the Blazor app.

[App.razor]

<LoadingScreen>
       <Router . . .
                . . .
                . . .
        </Router>
</LoadingScreen>

Please refer to this link for more details.

Permalink

Languages are changed by using localization in the Blazor server-side application. In the following example, the languages are changed from English to French and vice versa by clicking a button.

[Startup.cs]

public class Startup
    {
      . . .
      . . .
              public void ConfigureServices(IServiceCollection services)
        {
            . . .
            services.AddLocalization();
            services.AddLocalization(options => options.ResourcesPath = "Resources");
        }
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
          . . .
                     var localizeOptions = new RequestLocalizationOptions()
                .SetDefaultCulture("en-US")
                .AddSupportedCultures("en-US", "fr-FR")
                .AddSupportedUICultures("en-US", "fr-FR");

            app.UseRequestLocalization(localizeOptions);
                       .  .  .
                       .  .  .
                       app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();
                . . .
            });
        }
    }

[Culture.cs]

. . .
using Microsoft.AspNetCore.Localization;
using Microsoft.AspNetCore.Mvc;
namespace BlazorAppLocale
{
    [Route("/[controller]")]
    [ApiController]
    public class Culture : ControllerBase
    {
        public ActionResult SetCulture()
        {
            IRequestCultureFeature culture = HttpContext.Features.Get<IRequestCultureFeature>();
            Response.Cookies.Append(
                CookieRequestCultureProvider.DefaultCookieName,
                CookieRequestCultureProvider.MakeCookieValue(
                    new RequestCulture(new string[] { "en-US", "fr-FR" }
                    .Where(option => option != culture.RequestCulture.Culture.Name)
                    .FirstOrDefault())));

            return Redirect("/");
        }
    }
}

Add the culture resource files in the Resources/Pages folder.

[Index.razor]

@page "/"
@inject Microsoft.Extensions.Localization.IStringLocalizer<Resource> locale

<h1>@locale["Hello World"]</h1>

@locale["Welcome to your new app."]

<SurveyPrompt Title="How is Blazor working for you?" />

Add the button for changing the language.

[MainLayout.razor]

@inject NavigationManager UriHelper

<div class="top-row px-4"> 
    <button class="btn btn-secondary" @onclick="OnSelected">Change Language</button>
</div>

@code {

    private void OnSelected()
    {
        UriHelper.NavigateTo("Culture", true);
    }
}

You can download the reference sample here.

Please refer to this link for more information.

Permalink

Blazor has a built-in InputFile component from .NET 5.0 that can be used to upload files to the server. You can check the file size in the OnChange event and upload or prevent uploading the files to the server.

[Index.razor]

@page “/”

<h3>File Upload</h3>

<InputFile OnChange=”OnInputFileChange” />

@if (file?.Size < 1000000)
{
    <p>Name: @file.Name</p>
    <p>Size in bytes: @file.Size</p>
    <p>Last modified date: @file.LastModified.DateTime.ToShortDateString()</p>
    <p>Content type (not always supplied by the browser): @file.ContentType</p>
}
else
{
    <p>File size exceeds more than 1MB</p>
}

@code {
    IBrowserFile file;

    void OnInputFileChange(InputFileChangeEventArgs e)
    {
        file = e.File;
        if (e.File.Size < 1000000)
        {
            // Upload files to the server from here
        }
    }
}

Note: Syncfusion offers a feature-rich, easy-to-use File Upload component for Blazor. You can check it out here.

Permalink

Raw HTML can be rendered in Blazor by using MarkupString. You can define the property and pass it to a parameter by using MarkupString.

[Index.razor]

@page "/"

<button class='btn btn-primary' @onclick="OnClickButtonEvent">Counter</button>

@((MarkupString)MyMarkup)

@code { 
    private int count = 0;
    public string MyMarkup;

    public void OnClickButtonEvent()
    {
        ++count;
        MyMarkup = "<div>Current count: <span style=\"color:red\"><b>" + @count + "</b></span></div>";
    }
}
Permalink

Yes, you can host and deploy the blazor server-side application without using Azure but by using AWS or Firebase. Here you can find the steps for hosting the blazor application using AWS.

  • Create the Blazor application 
  • Publish the application using the context menu from the Solution in Solution Explorer in Visual Studio.
  • Click Publish. If there is no error, your application will be published successfully.

Host the application to AWS: https://topswagcode.com/2019/03/05/Hosting-Blazor-Apps/#AWS

Host the application to Firebase: https://dzone.com/articles/hosting-a-blazor-application-on-firebase 

Permalink

You need to add the Response Caching Middleware to the service collection in the startup class.

public void ConfigureServices(IServiceCollection services)
    {
       services.AddResponseCaching();
    }

Then, you can configure the app to use the middleware with the UseResponseCaching extension method, which adds the middleware to the Startup.Configure

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    app.UseResponseCaching();   
 }

Refer to this thread for more information.

Permalink

The AuthorizeView component supports policy-based authorization. You can use the Policy parameter for policy-based authorization.

<AuthorizeView Policy="IsShowContent">
   <p>You can only see the content if enabled the IsShowContent policy.</p>
</AuthorizeView>

Policy based authorization in Asp.Net Core

The policies are registered in the application Startup classes ConfigureServices method.

public void ConfigureServices(IServiceCollection services)
    {
        services.AddAuthorization(config =>
        {
            config.AddPolicy("IsShowContent", policy => policy.RequireClaim("IsShowContent", "true"));
        });
    }
Permalink

The Blazor framework includes synchronous and asynchronous lifecycle methods. You can load the full page asynchronously using the below methods,

  • OnInitializedAsync – It is invoked when the component is ready to start and has received its initial parameters from its parent in the render tree.
protected override async Task OnInitializedAsync()
{
await ...
}
  • OnParametersSetAsync – It is invoked when the component is initialized and has received its first set of parameters from its parent component.
protected override async Task OnParametersSetAsync()
{
    await ...
}
  • OnAfterRenderAsync – It is invoked after a component has finished rendering. The firstRender is set to true at first time when the component instance is rendered.
protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await ...
    }
}

Permalink

A Progressive Web Application is a Single Page Application that uses modern browser APIs, and  performs like a desktop app. It can work offline and load instantly, and independent of network speed.

Find the steps for create PWA with blazor app:

  • Create a project from the PWA template
  • Run the application, after creating the app
  • After it launched in the browser, there we have the option for installing the app (PWA)

  • Once installed, the app appears in its own window without an address bar.

Please refer to the documentation link for more details: https://docs.microsoft.com/en-us/aspnet/core/blazor/progressive-web-app?view=aspnetcore-3.1&tabs=visual-studio#create-a-project-from-the-pwa-template

Permalink

You can refresh the Blazor component using the SignalR concept without reloading the page. When using SignalR, saving the changes in one page notifies the changes made to other clients. During the notification process, call the data loading method to reload the changes made to that component without reloading the entire page.

@code{

    public List<Order> Orders { get; set; }
    private HubConnection hubConnection;

    protected override void OnInitialized()
    {
        hubConnection = new HubConnectionBuilder()
        .WithUrl(NavigationManager.ToAbsoluteUri("/chathub"))
        .Build();

        hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
        {
            LoadData(); //update the data
            StateHasChanged();//Refresh the component using updated data
        });

       await hubConnection.StartAsync();

    }

    protected async void LoadData()
    {
        //load all the orders from the server.
    }
}

Please refer to the documentation link for more details: https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr-blazor-webassembly?view=aspnetcore-3.1&tabs=visual-studio

Permalink

From .NET 5 Preview 7, Blazor components trim insignificant whitespaces to achieve better performance. This has been implemented as a result of the finding that 40% of the rendering time is consumed by whitespace nodes. If whitespace nodes removal causes unexpected behavior, you can simply enable it by using the @preservewhitespace directive.

@using System.Linq

@preservewhitespace true
 
<ul>
    @foreach (var item in forecasts)
    {
        <li>
            Temperature: @item.TemperatureC
        </li>
    }
</ul>
 
@code {
    private WeatherForecast[] forecasts;
 
    protected override void OnInitialized()
    {
        forecasts = Enumerable.Range(1, 10).Select(x => new WeatherForecast()
        {
            TemperatureC = x
        }).ToArray();
    }
 
    public class WeatherForecast
    {

        public int TemperatureC { get; set; }
 
    }
}

More details about preservewhitespace directive can be found here.

Permalink

You can use the IHttpContextAccessor.HttpContext.Response.HasStarted property to check whether the application is pre-rendering or not.  HasStarted specifies that the response header has been sent to the client. If HasStarted is set to false, it means that the application is still pre-rendering and client connection is not yet established.

Refer to the following code sample.

@using Microsoft.AspNetCore.Http;
 
<button @onclick="@onClick"> Click </button>
 
@code {
    [Inject]
    protected IHttpContextAccessor httpContextAccessor { get; set; }
 
    private void onClick()
    {
        var isPreRendering = !this.httpContextAccessor.HttpContext.Response.HasStarted;
    }
}

The HttpContextAccessor service should be registered by calling the AddHttpContextAccessor method in the Startup.cs.


public class Startup
{
    . . . . .
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddRazorPages();
        services.AddServerSideBlazor();
        services.AddSingleton<WeatherForecastService>();
        services.AddHttpContextAccessor();
    }
    . . . . . 
}

Permalink

Configurations loaded by the Blazor WebAssembly can be accessed by injecting IConfiguration services. Using IConfiguration, the values from wwwroot/appsettings.json and wwwroot/appsettings.{ENVIRONMENT}.json files can be accessed.

wwwroot/appsettings.json

{
  "message":  "Blazor is awesome."   
}

Index.razor

@inject Microsoft.Extensions.Configuration.IConfiguration config
 
<span>@config["message"]</span>

More information about configuration can be found here.

Permalink

You can check whether the current app is Blazor server-side or web assembly using the “IJSInProcessRuntime” interface. In the following example, I have checked whether the app is a web assembly or server side on button click.

<button @onclick="@onClick"> Click </button>

@code {

    [Inject]
    protected IJSRuntime jsRuntime { get; set; }

    private void onClick()
    {
        var isWebAssembly = this.jsRuntime is IJSInProcessRuntime;
    }
}
Permalink

A page is reloaded/refreshed automatically at a specified interval using “NavigationManager” in OnAfterRender() method. Here the NavigateTo(“url”, forceLoad: true) method, is used to force load the browser based on the URI.

@inject NavigationManager uriHelper;

@using System.Threading;

<h1>Hello, world!</h1>

Welcome to your new app.

@code {
    protected override void OnAfterRender(bool firstRender)
    {
        if (firstRender)
        {
            var timer = new Timer(new TimerCallback(_ =>
            {
                uriHelper.NavigateTo(uriHelper.Uri, forceLoad: true);
            }), null, 2000, 2000);
        }
    }
}
Permalink

In Blazor, “StateHasChanged” is used to re-render a page. When changes are detected in components, a page is refreshed. In the following example, a button click increments the count on time interval automatically.

@using System.Threading;

<p>Current count: @currentCount</p>

<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>

@code {

    private int currentCount = 0;

    private void IncrementCount()
    {
        var timer = new Timer(new TimerCallback(_ =>
        {
            currentCount++;
            InvokeAsync(() =>
            {
                StateHasChanged();
            });
        }), null, 1000, 1000);
    }
}
Permalink

Autocomplete enables the user to predict the value. The browser will show options to fill the field when a user starts typing in a field, based on earlier typed values. The code example shows how to enable autocomplete using an input element.

<input id="name" type="text" autocomplete="on" />

If you want to enable the autocomplete from your own database or own set of options, you can go with third party components such as Syncfusion Autocomplete.

Permalink

The HTML “progress” element is used to show the progress. In the following code example, start and stop of progress can be executed on button click.

<progress value="@progressValue" max="100" style="width: 100%">@(progressValue.ToString() + " %")</progress>

<button @onclick="@startProgress">Start</button>

@code {

    private int progressValue { get; set; }

    private void startProgress()
    {
            for (int i = 0; i < 1000; i++)
            {
                this.progressValue = i;
            }
    }
 
}
Permalink

In Blazor server server side application, CircuitOptions detailed error is shown using AddServerSideBlazor().AddCircuitOptions() method. This displays the details of the circuit error in the browser. Find the code snippet to enable the circuit option.

public void ConfigureServices(IServiceCollection services)
{
    services.AddRazorPages();
    services.AddServerSideBlazor().AddCircuitOptions(e=> {
        e.DetailedErrors = true;
    });
}
Permalink

You can show the confirmation dialog box before deleting a row in a table. The following code example shows the confirmation dialog box on delete button click.

<button @onclick="@onDelete">Delete</button>

@if (Show)
{
    <div class="modal" tabindex="-1" role="dialog" style="display: @(Show ? "block" : "none")">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">Confirm Dialog</h5>
                </div>
                <div class="modal-body">
                    <p>You have unsaved changes in this page. Do you still want to leave this page? </p>
                </div>
                <div class="modal-footer">
                    <button type="button" class="btn btn-primary" @onclick="@(()=> this.Show=false)">Ok</button>
                    <button type="button" class="btn btn-secondary" data-dismiss="modal" @onclick="@(()=> this.Show=false)">Close</button>
                </div>
            </div>
        </div>
    </div>
}
@code {

    public bool Show { get; set; } = false;

    private void onDelete()
    {
        this.Show = true;
    }
}
Permalink

To upload files in Blazor applications, install the NuGet package, BlazorInputFile. This package has the component, Blazor input file that is used to upload files.
You also need to include the input file scripts in HTML and add BlazorInputs to the _Imports.razor file.

[_Host.cshtml]

  <script src="_content/BlazorInputFile/inputfile.js"></script>
[index.razor]

@page "/upload"

<h3>Upload</h3>

<InputFile OnChange="HandleFileSelected"  class="btn-primary"/>

@if (file != null)
{
    <p>Name: @file.Name</p>
    <p>Size in bytes: @file.Size</p>
    <p>Last modified date: @file.LastModified.ToShortDateString()</p>
    <p>Content type (not always supplied by the browser): @file.Type</p>
}

@code {
    IFileListEntry file;

    void HandleFileSelected(IFileListEntry[] files)
    {
        file = files.FirstOrDefault();
    }
}

You can handle multiple file uploads by adding multiple attribute to the InputFile component.

@page "/multiupload"

<h3>Multiple File Upload</h3>

<InputFile multiple OnChange="HandleFileSelected"  class="btn-primary"/>

@if (file != null)
{
   <p>Name: @file.Name</p>
   <p>Size in bytes: @file.Size</p>
    <p>Last modified date: @file.LastModified.ToShortDateString()</p>
    <p>Content type (not always supplied by the browser): @file.Type</p>
}

@code {
    IFileListEntry file;

    void HandleFileSelected(IFileListEntry[] files)
    {
        file = files.FirstOrDefault();
    }
}

Please refer to this link here for more information on file uploading in Blazor.

Note: Syncfusion offers feature rich as well as easy to use file upload component. For more information, please check the link.

Permalink

Blazor detects the UI changes in common scenarios like EventCallback (button click, dropdown select, etc.), and refreshes the component. However, there are some situations in an app where a UI refresh needs to be triggered manually to re-render the component. The StateHasChanged method is used to force re-render a component UI.

@using System.Threading;

<h1>@Count</h1>

<button @onclick=@StartCountdown>Start Timer</button>

@functions {
    private int Count { get; set; } = 10;

    void StartCountdown()
    {
        var timer = new Timer(new TimerCallback(_ =>
        {
            if (Count > 0)
            {
                Count--;

                // Note that the following line is necessary because otherwise
                // Blazor would not recognize the state change and not refresh the UI
                InvokeAsync(() =>
                {

                    StateHasChanged();
                });
            }
        }), null, 1000, 1000);
    }
}
Permalink

Blazor application renders UI as a HTML content in client-side (browser). So, based on the width of the viewport in a device you can determine if it is a Desktop or a Mobile device and thus design responsive web pages accordingly.

The meta tag named “viewport” is used to design the webpage responsiveness and this is included in all Blazor applications, _Host.cshtml file in Blazor server-side application and index.html file in Blazor Web Assembly application. CSS styling makes designs responsive in Blazor apps.

For more details, refer to this link.

Permalink

String comparison with case insensitivity can be carried out using the String.Compare method, where the first and second parameters are the strings to be compared and the third parameter is for ignoring case sensitivity (case insensitive comparison).

Refer to the following code.

@page "/"

<h1>Case in-sensitive string comparision</h1>

<br />

<EditForm Model="@_stringCompare">
    String 1:
    <InputText id="string1" @bind-Value="_stringCompare.String1" />
    <br />
    String 2:
    <InputText id="string2" @bind-Value="_stringCompare.String2" />
    <br />
</EditForm>

<br />

<button @onclick="Compare">Compare</button>

<br />
<br />

<p>@Output</p>

<br />

@code {

    private StringCompare _stringCompare = new StringCompare();
    public string Output = "";

    public class StringCompare
    {
        public string String1 { get; set; }
        public string String2 { get; set; }
    }

    public async void Compare()
    {
        int CheckValue = String.Compare(_stringCompare.String1, _stringCompare.String2, true);
        Output = "Entered Strings are " + (CheckValue == 0 ? "" : "not ") + "Similar";
        await Task.Run(() => TimeOutMethod());
        Output = "";
        await Task.CompletedTask; 
    }

    void TimeOutMethod() => Task.Delay(3000).Wait();
}

You can download the reference sample here.

Permalink

The property value in the select control can be used to set the default value in select control.

@page "/dropdown"

<select class="form-control" value="@defaultValue " @onchange="@OnSelect" style="width:150px">
       @foreach (var template in templates)
        {
     <option value=@template>@template</option>
         }
 </select>

<h5>@selectedString</h5>

@code {
List<string> templates = new List<string>() { "America", "China", "India", "Russia", "England" };
string selectedString = "";
string defaultValue = "India";
void OnSelect(ChangeEventArgs e)
{
       selectedString = "Selected Country is: " + e.Value.ToString();
}
    }
Permalink

To add Bing Maps to a Blazor application follow the steps.

  • Include the Bing Maps Web API scripts in the index.html/_Host.cshtml, This is used to retrieve the Bing Maps-related information by sending a request to the Bing Maps server and loading the same to the Blazor application.
  • Initialize maps in a Blazor application by using a JavaScript interop in the razor file [index.razor].

Please find the sample below.

[script.js]
function loadBingMap() {
      var map = new Microsoft.Maps.Map(document.getElementById('map'), {});
      var pushpin = new Microsoft.Maps.Pushpin(map.getCenter(), null);
      map.entities.push(pushpin);
      return "";
}
[index.html/_Host.cshtml]

<script src='https://www.bing.com/api/maps/mapcontrol?callback=GetMap&key=api_key' type='text/javascript'></script>
@page "/bingmaps"
@inject IJSRuntime JSRuntime

<h1>Display Bing Map</h1>
<div id="map" style="height:500px;width:100%;"> </div>

@code {
    
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
if (firstRender)
{
       await JSRuntime.InvokeVoidAsync("loadBingMap", null); 
  }
     }

}

Permalink

To use jQuery UI components in a Blazor application follow the steps:

  • Reference the source scripts for jQuery and its UI components.
  • Create the elements required for rendering jQuery UI components in the razor page [index.razor].
  • Initialize the jQuery components in the OnAfterRender lifecycle method in your Blazor application by using the JavaScript Interop’s InvokeVoidAsync method.

Refer to the following code sample.

[_Host.cshtml]

….
<link rel="stylesheet" href="https://code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
    <script src="https://code.jquery.com/jquery-1.12.4.js"></script>
    <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script>
    <script src="~/script.js"></script>
….

[index.razor]

@page "/"
@inject IJSRuntime jsRuntime

<h1>jQuery UI Components in Blazor</h1>

<br />

<h2>jQuery Accordion Component</h2>

<br />

<div id="accordion">
    <h3>ASP.NET</h3>
    <div>
        <p>
            Microsoft ASP.NET is a set of technologies in the Microsoft .NET Framework for building Web applications and XML Web services.
            ASP.NET pages execute on the server and generate markup such as HTML, WML, or XML that is sent to a desktop or mobile browser.
            ASP.NET pages use a compiled,event-driven programming model that improves performance and enables the separation of application logic and user interface.
        </p>
    </div>
    <h3>ASP.NET MVC</h3>
    <div>
        <p>
            The Model-View-Controller (MVC) architectural pattern separates an application into three main components: the model, the view, and the controller.
            The ASP.NET MVC framework provides an alternative to the ASP.NET Web Forms pattern for creating Web applications.
            The ASP.NET MVC framework is a lightweight, highly testable presentation framework that (as with Web Forms-based applications) is integrated with existing ASP.NET features, such as master pages and membership-based authentication.
        </p>
    </div>
    <h3>JavaScript</h3>
    <div>
        <p>
            JavaScript (JS) is an interpreted computer programming language.
            It was originally implemented as part of web browsers so that client-side scripts could interact with the user, control the browser, communicate asynchronously, and alter the document content that was displayed.
            More recently, however, it has become common in both game development and the creation of desktop applications.
        </p>
    </div>
</div>

<br />

<div class="jquery-btn">
    <button>Click Me</button>
</div>

<br />

<p>Clicked: <span class="click-count">0</span></p>

<br />

@code {
    protected override async void OnAfterRenderAsync(bool firstRender)
    {
        await jsRuntime.InvokeVoidAsync("renderjQueryComponents");
        await base.OnAfterRenderAsync(firstRender);
    }
}

[script.js]

var clickCount = 0;

function renderjQueryComponents() {
    $("#accordion").accordion();
    $(".jquery-btn button").button();
    $(".jquery-btn button").click(function () {
        console.log('Clicked');
        $('.click-count')[0].innerText = ++clickCount;
    });
}

You can download the reference sample here.

Permalink

First to access browser seesionStorage in Blazor apps, write a custom code or use a third party package. The accessed data can be stored in the localStorage and sessionStorage.  The localStorage is scoped to the user’s browser. If the user reloads the page or closes and reopens the browser, the state persists. Session storage is similar to the local storage but the data in the session storage will be cleared after the session.

Use the Blazored.SessionStorage package to store the session data in Blazor. For this install the package and add the service to the application.

[startup.cs]
using Blazored.SessionStorage;

public void ConfigureServices(IServiceCollection services)
{
         services.AddBlazoredSessionStorage();
}
[index.razor]
@page "/"
@inject Blazored.SessionStorage.ISessionStorageService sessionStorage

<h2>@Name</h2>
<button @onclick="Clear">Clear Session</button>
@code {
    public string Name;
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await sessionStorage.SetItemAsync("ID", "20019");
        await sessionStorage.SetItemAsync("Name", "John Smith");
        Name = "ID: " + await sessionStorage.GetItemAsync<string>("ID") + "Name : " + await sessionStorage.GetItemAsync<string>("Name");
    }
   public async void Clear()
   { 
    //this will clear the session data 
     await sessionStorage.ClearAsync();
    }
}

Reference link: https://github.com/blazored/SessionStorage

Permalink

To access browser localStorage in Blazor apps, write a custom code or use a third party package. The difference between localStorage and sessionStorage  is: The localStorage is scoped to the user’s browser. If the user reloads the page or closes and reopens the browser, the state persists. Session storage is similar to local storage but the data in the session storage will be cleared after the session.

The Blazored.LocalStorage package can be used to access the browser’s local storage in Blazor. For this you need to install the package and add the service to the application.

[startup.cs]

public void ConfigureServices(IServiceCollection services)
{
         services.AddBlazoredLocalStorage();
}
[index.razor]
@page "/"
@inject Blazored.LocalStorage.ILocalStorageService localStorage

<h2>@Name</h2>
<button @onclick="Clear">Clear LocalStorage</button>
@code {
    public string Name;
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        await localStorage.SetItemAsync("ID", "20019");
        await localStorage.SetItemAsync("Name", "John Smith");
        Name = "ID: " + await localStorage.GetItemAsync<string>("ID") + "Name : " + await localStorage.GetItemAsync<string>("Name");
    }
    public async void Clear()
   {
    //this will clear the local storage 
     await localStorage.ClearAsync();
    }

}

To access the local storage using the OnInitialized method, disable the ServerPrerender in _Host.cshtml.

Reference link: https://chrissainty.com/blazored-local-storage-v0-3-0-released/

Permalink

In Blazor, there are three ways to use different CSS files in different pages .

1. Use inline <style></style> tag to define the custom styling for the page.

2. Include a new CSS file in the page by using a JavaScript interop in the OnInitialized method.

[script.js]

function includeCss() {
     var element = document.createElement("link");
     element.setAttribute("rel", "stylesheet");
     element.setAttribute("type", "text/css");
     element.setAttribute("href", "css/external.css");//location of the css that we want     include for the page
     document.getElementsByTagName("head")[0].appendChild(element);
}
[index.razor]

@page “/”

<h1>Blazor Application</h1>

@code{
    protected override async void OnInitialized()
    {
        await JSRuntime.InvokeAsync<object>("includeCss");
     }
    }

3. Usedirect links of the CSS file via the <link> HTML element with its local or online reference in the href attribute.

<link href="StyleSheet.css" rel="stylesheet" />
Permalink

To add Google Maps to a Blazor application, use the Google Maps API script. To initialize Google Maps in Blazor we need to use a JavaScript interop.

Add the following scripts to ~/Pages/_Host.cshtml for Server Blazor app or ~/wwwroot/index.html for Blazor WebAssembly app.

[_Host.cshtml/index.html]

<head>
    <script src="~/script.js"></script>
    <script type="text/javascript" src="https://maps.googleapis.com/maps/api/js?key=&callback=initMap"></script>
</head>
[script.js]

function initialize() {
var latlng = new google.maps.LatLng(40.716948, -74.003563);
var options = {
     zoom: 14, center: latlng,
      mapTypeId: google.maps.MapTypeId.ROADMAP
};
var map = new google.maps.Map(document.getElementById ("map"), options);
}
[index.razor]

@page "/"

@inject IJSRuntime JSRuntime

<h1>Display Google Map</h1>
<div id="map" style="height:500px;width:100%;">
</div>

@code{
    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await JSRuntime.InvokeVoidAsync("initialize", null); 
        }
    }
}

In the above example, Google Maps is initialized in the OnAfterRenderAsync life cycle method. By invoking it using a JavaScript interop, this will initialize Google Map API when the page is rendered.

You can download the reference sample here.

Note: If you’d like to know how to render Google Maps in Syncfusion Blazor Map, take a look at our documentation section.

Permalink
  • Razor is a templating engine that combines C# with HTML to build dynamic web content.
  • Blazor is a component-based, single-page app framework for building client-side web apps using .NET that works well with all modern browsers via WebAssembly for client-side Blazor. Server-side Blazor ASP.NET Core app runs on server and makes use of SignalR connection to communicate with the client (browser). It works with all modern browsers. In other words, Blazor is a hosting model for Razor components.

For detailed information, refer to these links:

Permalink

Blazor is a component-based, single-page web app framework build using .NET.  It works well with all modern browsers via WebAssembly for client-side Blazor. Server-side Blazor ASP.NET Core app runs on server and makes use of SignalR connection to communicate with the client (browser).

Permalink

We can perform asynchronous calls in a Blazor application using async and await keywords for calling any asynchronous Task or performing any operation.

Refer to the following code snippet.

[Index.razor]

@page "/"

<button @onclick="Compare">Compare</button>
<br />
<p>@content</p>

@code {

    public string content = "Some Text";

    public async void  Compare()
    {
        await Task.Run(() => TimeOutMethod());
        content = "";
        await Task.CompletedTask;
        
    }

    void TimeOutMethod() => Task.Delay(3000).Wait();

}
Permalink

You can change the default icon provider for Blazor by importing the required icons in the site.css (\wwwroot\css\site.css). The imported icons can be used throughout the application. In the sample, I’ve imported the Material theme icons and used them.

[site.css]

@import url('https://fonts.googleapis.com/icon?family=Material+Icons');
[~/Shared/NavMenu.razor]

<li class="nav-item px-3">
     <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
          <i class="material-icons"> accessibility </i>Home
     </NavLink>
</li>
<li class="nav-item px-3">
      <NavLink class="nav-link" href="counter">
           <i class="material-icons">autorenew</i> Counter
      </NavLink>
 </li>
<li class="nav-item px-3">
      <NavLink class="nav-link" href="fetchdata">Fetch data
      </NavLink>
</li>

In the sample, we have changed the default icons to the Material icons for the home page and counter.

Permalink

You can remove the About section from a Blazor application in the MainLayout.razor page.
Remove the following code from the ~/Shared/MainLayout.razor page

<div class="top-row px-4">
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
Permalink

Currently there is no direct Canvas support in WebAssembly. In order to draw using Canvas, you can use the third-party, free Blazor.Extensions.Canvas library. Add Blazor.Extensions.Canvas NuGet to your project and add the following code snippet to draw a rectangle. It draws shapes in Blazor with the reference that is created for the Canvas element in the Razor page.

[index.html/_host.cshtml]
<head>

 <script src="_content/Blazor.Extensions.Canvas/blazor.extensions.canvas.js"></script>

</head>
[index.razor]

@page "/"
@using Blazor.Extensions; 
@using Blazor.Extensions.Canvas
@using Blazor.Extensions.Canvas.Canvas2D;

<BECanvas Width="300" Height="400" @ref="_canvasReference"></BECanvas>

@code {
    private Canvas2DContext _context;

    protected BECanvasComponent _canvasReference;

    protected override async Task OnAfterRenderAsync(bool firstRender)
    {
        this._context = await this._canvasReference.CreateCanvas2DAsync();
        await this._context.SetFillStyleAsync("red");

        await this._context.FillRectAsync(10, 100, 100, 100);

        await this._context.SetFontAsync("38px Calibri");
        await this._context.StrokeTextAsync("Hello Blazor!!!", 5, 100);
 }
}
Permalink

You can use a third party API, such as Ipify, to get the IP address of the current request in Blazor. The script api.ipify will return the IP address in JSON format. But this is a workaround. As of now, there is no way to achieve this. In the following code snippet, the IP address will be retrieved from the Ipify API through a JS interop call to the Blazor server.

[_Host.cshtml/index.html]

<script>
function GetAddress() {
    var script = document.createElement("script");
    script.type = "text/javascript";
    script.src = "https://api.ipify.org?format=jsonp&callback=DisplayIP";
    document.getElementsByTagName("head")[0].appendChild(script);
};
function DisplayIP(response) {
    document.getElementById("text").innerHTML = "Your IP Address is " + response.ip;
}
</script>
[index.razor]

@page "/"
@inject IJSRuntime jsRuntime

<button @onclick="GetIp">Get IP!!!</button>
<textarea id="text" style="width:50%;height:40px;" />

@code{
          public async Task GetIp()
          {
                 await jsRuntime.InvokeAsync<object>("GetAddress");
          } 
}
Permalink

We can bind properties to a list by binding every value in the list to each list element using a for loop. Then, if the property gets updated in the list, the HTML DOM will update the concerned item of the list element.

Refer to the following code snippet for further details.

<h1>Bind List</h1>

<button class="btn btn-primary" @onclick="Generate">Generate and Bind to List</button>

@if (list != null)
{
    @foreach (var item in list)
    {
        <li>@item</li>
    }
}

@code {
    List<int> list;
    const int cMaxNumbers = 10;

    protected void Generate()
    {
        list = new List<int>(cMaxNumbers);
        for (int i = 0; i < cMaxNumbers; i++)
        {
            list.Add(i);
        }
    }
}

You can download the reference sample here

Permalink

Blazor will check for an HTML ID on initializing the HTML element. If such an ID does not exist on the page, then it will use the default handler to display messages. To display custom messages  on connection loss, we can define a div element with the ID components-reconnect-modal in the body of _Host.cshtml to manipulate the overlay that shows up in the case of a connection loss. If this element exists, this element’s class will be :

components-reconnect-show: A lost connection. The client is attempting to reconnect. Show the modal. Then, you can apply your custom styling to the screen overlay with CSS. If you want to remove them all, you can just choose not to display them at all.

components-reconnect-hide: An active connection is re-established to the server. Hide the modal.

components-reconnect-failed: Reconnection failed, probably due to a network failure. To attempt reconnection, call window.Blazor.reconnect().

components-reconnect-rejected: Reconnection rejected. The server was reached but refused the connection, and the user’s state on the server is lost. To reload the app, call location.reload().

Refer to this link for more details: https://docs.microsoft.com/en-us/aspnet/core/blazor/hosting-model-configuration?view=aspnetcore-3.1#reflect-the-connection-state-in-the-ui

[_Host.cshmtl]

<body>
……

<div id="components-reconnect-modal" class="my-reconnect-modal components-reconnect-hide">
<div class="show">
    <p>
        // Message when attempting to connect to server
    </p>
</div>
<div class="failed">
    <p>
        // Message when failing to connect
    </p>
</div>
<div class="rejected">
    <p>
        // Message when refused
    </p>
</div>
</div>

……
<app>
    @(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
</app>

</body>
[site.css]

    .my-reconnect-modal > div {
        position: fixed;
        top: 0;
        right: 0;
        bottom: 0;
        left: 0;
        z-index: 1000;
        overflow: hidden;
        background-color: #fff;
        opacity: 0.8;
        text-align: center;
        font-weight: bold;
    }

    .components-reconnect-hide > div {
        display: none;
    }

    .components-reconnect-show > div {
        display: none;
    }

    .components-reconnect-show > .show {
        display: block;
    }

    .components-reconnect-failed > div {
        display: none;
    }

    .components-reconnect-failed > .failed {
        display: block;
    }

    .components-reconnect-refused > div {
        display: none;
    }

    .components-reconnect-refused > .refused {
        display: block;
    }

You can download the reference sample here

Permalink

To set the focus to a HTML element in Blazor, use the JavaScript interop to pass the HTML element and then use focus JavaScript method.

[script.js]

window.SetFocusToElement = (element) => {
         element.focus();
};
[index.razor]

@inject IJSRuntime jsRuntime

<div class="jumbotron" tabindex="0"  @ref="myDiv">
</div>

@code {
    string KeyPressed = "";
    protected ElementReference myDiv;  // set the @ref for attribute

    protected async override Task OnAfterRenderAsync(bool firstRender)
    {
        if (firstRender)
        {
            await jsRuntime.InvokeVoidAsync("SetFocusToElement", myDiv);
        }
    }
}
Permalink

While making an API call, create and run an asynchronous task with the Run method to notify the wait using a spinner. The completion of the task can be notified using the  CompletedTask property.

[index.razor]

@page "/"

<style>
    .loader {
        border: 5px solid #f3f3f3;
        border-radius: 50%;
        border-top: 5px solid #f58205;
        width: 30px;
        height: 30px;
        -webkit-animation: spin 2s linear infinite; /* Safari */
        animation: spin 2s linear infinite;
    }
    /* Safari */
    @@-webkit-keyframes spin {
        0% {
            -webkit-transform: rotate(0deg);
        }
        100% {
            -webkit-transform: rotate(360deg);
        }
    }
    @@keyframes spin {
        0% {
            transform: rotate(0deg);
        }
        100% {
            transform: rotate(360deg);
        }
    }
</style>

<h1>Counter</h1>

<p>
    Current count: <div class="@(spin ? "loader" : "")"> @(spin?"":currentCount.ToString()) </div>
</p>

<button class="btn btn-primary" @onclick="@IncrementCount"> Click me </button>
<button class="btn btn-dark" @onclick="@AsyncCallBack"> API Call Back </button>

@code {
    int currentCount = 0;
    bool spin = false;
    void IncrementCount()
    {
        currentCount++;
    }

    async Task AsyncCallBack()
    {
        spin = true;
        await Task.Run(() => APICallBack());  //<==check this!!!
        currentCount++;
        spin = false;
        await Task.CompletedTask;
    }

    void APICallBack() => Task.Delay(1500).Wait();
}

Output:

Permalink

The lifecycle methods OnAfterRenderAsync and OnAfterRender are called only when a component has finished rendering. The element and component references are populated at this point. By using these methods, the user can activate third-party JavaScript libraries that operate based on the DOM elements.

Permalink

Blazor notifies the UI changes automatically whenever the bound property is changed in a button click, input text, dropdown, etc.Blazor triggers the StateHasChanged() method to notify the change. However, there are some exceptional cases where the user has to manually call the StateHasChanged() method to notify that the UI has been updated.

By calling the StateHasChanged(), Blazor can manually be notified when to rerender its UI. This method will tell Blazor when to refresh the UI.

@using System.Threading;

<h1>@Count</h1>

<button @onclick=@StartCountdown>Start Timer</button>

@functions {
    private int Count { get; set; } = 10;

    void StartCountdown()
    {
        var timer = new Timer(new TimerCallback(_ =>
        {
            if (Count > 0)
            {
                Count--;

                // Note that the following line is necessary because otherwise
                // Blazor would not recognize the state change and refresh the UI
                InvokeAsync(() =>
                {
                    StateHasChanged();
                });
            }
        }), null, 1000, 1000);
    }
}

In the above example, when the button is clicked, the UI will refresh for every count down of the timer since StateHasChanged method has been called to refresh the UI.

Permalink

You can delay a task in Blazor by using the Task.Delay() method where the time set for the task to be delayed before proceeding to the next.

<h3>Timer: @Timer</h3>

@code {
    [Parameter] 
    public int Timer { get; set; } = 5;

    public async void StartTimerAsync()
    {
        while (Timer > 0)
        {
            Timer--;
            StateHasChanged();
            await Task.Delay(1000);
        }
    }

    protected override void OnInitialized()
        => StartAsync();
}
Permalink

When StateHasChanged is called, it runs change detection on the current component and its descendants. Blazor is clever enough to rerender the components that have changes.

<h3>StateHasChanged</h3>

<button class="btn btn-primary" @onclick="Generate">Generate List</button>
<button class="btn btn-primary" @onclick="ChangeOneRow">Change State</button>

@if (list != null)
{
       @foreach (var item in list)
       {
               <li>@item</li>
       }
}

@code {
    List<int> list;
    const int cMaxNumbers = 10;

    protected void Generate()
    {
        list = new List<int>(cMaxNumbers);
        for (int i = 0; i < cMaxNumbers; i++)
        {
            list.Add(i);
        }
    }

    protected void ChangeOneRow()
    {
        list[0] = 123456;
        StateHasChanged();
    }
}

In the above example, only the first list will be re-rendered.

Permalink

The StateHasChanged method is called whenever a bound property is changed or a UI event triggered for an instance. This notifies the Blazor that the component should rerender it.

For example, when a button is clicked in the index page, the index component rerenders (no need to call StateHasChanged) because the button’s parent is an index; but when it has a child component it has be notified to render as the parent has changed.

Permalink

Blazor provides both synchronous and asynchronous initialization lifecycle methods to perform additional operations on components during initialization and rendering. Initialization methods are:

  • OnInitialized:  Override this method in components for synchronous operations.
  • OnInitializedAsync:   Override this method in components for asynchronous operations.

OnInitialized and OnInitializedAsync are executed when the component is initialized after having received its initial parameters from its parent component in the render tree.

Use OnInitializedAsync when the component performs an asynchronous operation and the changes should refresh the component when the operation is completed. Refer to this link for more details.

Permalink

You can call the preventDefault action in onclick event of an anchor tag. Refer to the following code sample to prevent opening a link when the link is clicked.

<a href="https://www.syncfusion.com/" target="_blank" @onclick:preventDefault>Syncfusion</a>

This feature was made available from .NET Core 3.1 Preview 2 for Blazor.

You can also perform custom action for onclick in the anchor tag by defining the same onclick event and mapping it to custom action.

<a href="https://www.syncfusion.com/" target="_blank" @onclick:preventDefault  @onclick="@OnClick">Syncfusion</a>
@code {
         public void OnClick(){
              //triggers on click
         }
}
Permalink

State in Blazor:

In Blazor, the user’s state is held in the server’s memory in a circuit. State Management refers to the persisting state of an application even after the connection is lost or disconnected.  The state held for a user’s circuit may be any of the following,

  • UI related data- component instances, rendered output
  • Property/field values of the component instances
  • Dependency injection service instance data

Need for State Management:

In Blazor, the application is connected through a circuit to the  server, which holds the user’s state and this can be lost or disconnected due to multiple reasons. Some of the reasons are as follows,

  • Large number of users accessing the server and increasing the memory used causing the pressure to disconnect the circuit.
  • Users reloading the application/webpage leading to circuit disconnection/loss.

Due to the above, user’s state may be lost and can also cause loss of crucial data gathered in the application such as,

  • Multistep webform
  • Shopping cart

When data is lost after completing processes with multiple steps or creating a shopping list, it results in unnecessary time consumption.  So, in Blazor, the data is stored in the local cache and state persists even when the circuit gets disconnected.

Persisting the State/State Management:

The three locations for persisting state in a Blazor application are as follows,

  • Server-side (Database)
  • Client-side (Browser)
  • URL

Server-side (Database):

To store data/state permanently or any data that spans multiple users or devices, the server-side database should be used.

Client-side (Browser):

Most suited when the user is actively creating transient data, that can be stored in the browsers,  localStorage and sessionStorage.

URL:

This is best suited when the data/state needs to persist when navigating from one page of the application to another.

For more information on state management, refer here.

Permalink

JSON (JavaScript Object Notation) is a lightweight data-interchange format and a text format that is completely language independent. In Blazor, JsonSerializer class helps serialize and deserialize JSON. It is present in the namespace System.Text.Json.

[index.razor]
@page "/"
@using System.Text.Json

<button @onclick="@SerializeDeserializeMethod">Serialize & Deserialize</button>

@code {
    public class User
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public string Address { get; set; }
    }

    User user = new User() {ID = 1, Name = "Manas", Address = "India"};

    void SerializeDeserializeMethod()
    {
        //for serialization
        string serializedString = System.Text.Json.JsonSerializer.Serialize(User1);
        //for deserialization
        User userCopy = System.Text.Json.JsonSerializer.Deserialize<User>(serializedString);
    }
}

In the sample using JsonSerialize.Serialize(object), the object user of class user is serialized and stored as a string, then using JsonSerialize.Deserialize<ClassName>(JsonObject) the string serializedString is deserialized with respect to class user as userCopy.

Permalink

Only server-side Blazor is supported by Microsoft’s Internet Explorer IE 11 when additional polyfills are used. Client-side Blazor is not supported by Internet Explorer due to incompatibility of WebAssembly. You need to add the following polyfills in the _Host.cshtml page to support Internet Explorer.

[_Host.cshtml]

//polyfills to be added for Internet Explorer

<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.6.5/core.min.js"></script>

<script src="https://polyfill.io/v3/polyfill.min.js?features=fetch"></script>
Permalink

To install Blazor project templates, update the .NET Core SDK to the latest version. Blazor server-side template is available by default when you create a new Blazor project in Visual Studio. To get the Blazor WebAssembly project template,  install them via the following command line.

dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.2.0-preview1.20073.1

Check this link for more information.

Permalink

Blazor has two hosting models, client-side and server-side. Blazor relies on WebAssembly (WASM) for running the Blazor application on the client-side (from browser end itself). The .NET runtime is downloaded with the app along with the app assembly and any required dependencies, then the application is executed directly from the browser UI thread.

Permalink

You can develop a native mobile app in Blazor using Experimental Mobile Blazor Bindings. This allows developers to develop mobile applications in C# and .NET for iOS and Android. It uses Razor syntax to define UI components and the underlying UI components are based on Xamarin.Forms native UI Components. Currently, it is in an experimental mode. 
Check this link to understand the concept: Mobile Blazor Bindings

Permalink

Blazor server-side supports almost all modern browsers out of the box except Microsoft’s Internet Explorer (IE 11), which needs Polyfills to be supported.

[_Host.cshtml]

//polyfills to be added for IE

<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.6.5/core.min.js"></script>

<script src="https://polyfill.io/v3/polyfill.min.js?features=fetch"></script>

Blazor WebAssembly (client-side) supports all the modern browsers except the Internet Explorer.
Check this link for more information.

Permalink

Blazor Server

In server code, configure SignalR in the Startup.cs class file as follows.

public void ConfigureServices(IServiceCollection services)
{
    ... ... ... ...
    services.AddSignalR();
    ... ... ... ...

}


public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    ... ... ... ...
    app.UseSignalR(routes => routes.MapHub<Blazor.NetCore.Server.SignalRHub.SignalRHub>("/signalRHub"));
    ... ... ... ...
}

And then create a SignalR hub class as follows.

    public class SignalRHub : Hub
    {
        public override Task OnConnectedAsync()
        {
            Clients.All.SendAsync("ReceiveMessage", "system", $"{Context.ConnectionId} joined the conversation");
            return base.OnConnectedAsync();
        }
        public void SendMessage(string name, string message)
        {
            Clients.All.SendAsync("ReceiveMessage", name, message);
        }

        public override Task OnDisconnectedAsync(System.Exception exception)
        {
            Clients.All.SendAsync("ReceiveMessage", "system", $"{Context.ConnectionId} left the conversation");
            return base.OnDisconnectedAsync(exception);
        }
    }

Blazor client

Create a Blazor app and add the package Blazor.Extensions.SignalR to the client. Then write the code to connect the Hub and event handler as follows.

@page "/signalr"
@using Blazor.Extensions
<div class="container">
    <input type="text" id="user" class="form-control" @bind="@userName" placeholder="User Name" /><br />
    <input type="text" id="message" class="form-control" @bind="@Message" placeholder="Message" /> <br />
    <input type="button" id="sendMessage" value="Send" class="btn btn-primary" @onclick="@SendMessage" />
    <ul id="discussion">
        @foreach (var message in messages)
        {
            <li>@message</li>
        }
    </ul>
</div>

@code {
    HubConnection connection;
    string userName = "";
    string Message = "";
    IList<string> messages = new List<string>();

    protected override async Task OnInitializedAsync()
    {
        connection = new HubConnectionBuilder().WithUrl("/signalRHub").Build();
        connection.On<string, string>("receiveMessage", this.ReceiveMessage);
        await connection.StartAsync();
    }

    Task ReceiveMessage(string name, string message)
    {
        messages.Add(name + " : " + message);
        StateHasChanged();
        return Task.CompletedTask;
    }

    async Task SendMessage()
    {
        await connection.InvokeAsync("SendMessage", userName, Message);
        Message = "";
    }
}
  1. OnInitializedAsync method, connect to the Web API.
  2. ReceiveMessage method, used in the SignalRHub class.
  3. ReceiveMessage method, concatenate the name and message parameters, and append them to a list.

The StateHasChanged method will update the bindings in the HTML. The SendMessage method will invoke the Send method in the hub with name and message parameters.

Reference link: https://docs.microsoft.com/en-us/aspnet/core/tutorials/signalr-blazor-webassembly?view=aspnetcore-3.1&tabs=visual-studio#add-the-signalr-client-library

Permalink

You have to use JS Interop to create a cookie in Blazor.

[Razor Page]

@page "/"
@inject IJSRuntime JSRuntime

@code {

    private async void CreateCookie(string name, string value, int days)
       {
            var test = await JSRuntime.InvokeAsync<string>("methods.CreateCookie", name, value, days);
       }
}

[Script file]

window.methods = {
    CreateCookie: function (name, value, days) {
     var expires;
     if (days) {
        var date = new Date();
         date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
          expires = "; expires=" + date.toGMTString();
     }
      else {
         expires = "";
     }
      document.cookie = name + "=" + value + expires + "; path=/";
   }    
}

Refer to to How do I create a cookie client-side using Blazor for more information.

Permalink

The NotFound template section in the App.razor can be used for handling 404 pages. The router shows this content if it hits a route that is not available, which is a 404 page.

<Router AppAssembly="@typeof(Program).Assembly">
    <Found Context="routeData">
        <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
    </Found>
    <NotFound>
        <LayoutView Layout="@typeof(MainLayout)">
            <p>Handled 404 page</p>
        </LayoutView>
    </NotFound>
</Router>

Create a component Page/Error.razor to display the 404 content. For more information, read about Blazor routing.

Permalink

Auto rebuild for Visual Studio is now available for Blazor Hosted Projects. Run the project with Ctrl + F5 (without the debugger) instead of F5 and on IIS express. Once .cs and .razor files are changed and saved across the solution, they are automatically rebuilt and the app restarted so that the changes can be seen by simply refreshing the browser.

Reference Link: https://devblogs.microsoft.com/aspnet/blazor-webassembly-3-2-0-preview-3-release-now-available/

Permalink

Share with

Share on twitter
Share on facebook
Share on linkedin

Couldn't find the FAQs you're looking for?

Please submit your question and answer.