Blazor FAQ - Tips and Tricks

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

Bundling is the process of combining multiple files into a single file. Minifying is the process of removing unnecessary data such as comments and extra spaces, as well as converting a large variable name into a smaller name without affecting its functionalities.

To bundle and minify the CSS and JS files in a Blazor application, follow these steps:

  1. Install the BuildBundlerMinifier NuGet package and reference it in the .csproj file, as shown.

    [.csproj]

        <Project Sdk="Microsoft.NET.Sdk.Web">
      ……………
     
      <ItemGroup>
        <PackageReference Include="BuildBundlerMinifier" Version="3.2.449" />
        ……………
      </ItemGroup>
     
    </Project>

  2. Create a new .json file named bundleconfig.json and add the following code to bundle and minify the CSS and JS files.

    [bundleconfig.json]

      [
      {
        "outputFileName": "wwwroot/css/bundle.min.css",
        "inputFiles": [
          "wwwroot/css/app.css",
          "wwwroot/css/site.css"
        ]
      },
      {
        "outputFileName": "wwwroot/scripts/bundle.min.js",
        "inputFiles": [
          "wwwroot/scripts/core.js",
          "wwwroot/scripts/index.js"
        ],
        "minify": {
          "enabled": true,
          "renameLocals": true
        },
        "sourceMap": false
      }
    ]

  3. After you build your application, the bundled and minified files are generated as shown in the following image. You can reference these files in your application based on the requirement.

    Output


    View Sample in GitHub

Permalink

SEO is an abbreviation for search-engine optimization, and it refers to the process of optimizing a website for search engines. In simpler words, it refers to the process of improving your website in order to increase its visibility when people use Google, Bing, and other search engines to find what they’re looking for.

The best way to make your Blazor WebAssembly application SEO-friendly is to work on the title, meta description, and H1 tag in the index.html common page or in individual pages based on your requirements and development activities. If you include keywords in the title, meta description, and H1 tag of your Blazor WebAssembly application, the app will appear near the top of search engine results when people search for general information using those keywords.

meta tags

Title: The title must be text-only and appears in the browser’s title bar or in the page’s tab.

meta title

H1 tag: The H1 tag will be displayed as the application’s top-level heading.

h1 tag

Meta description:  The meta description will be displayed as compressed content just below the search-related link.

meta description

Meta keywords: If anyone searches for a keyword mentioned in your Blazor application, it will appear at the top of the search engine results. However, Googlebot no longer considers meta keywords to be SEO-friendly.

meta keywords

Note: Make sure that your title, H1 tag, and meta description are unique. If the description or title is too long, Google will limit the content to a specific range. Follow these guidelines to avoid unwanted content loss:

  • Title: should be between 20 and 70 characters long.
  • Meta description: should be between 100 and 160 characters long.
  • H1: should be between 20 and 70 characters long.
Permalink

SEO is an abbreviation for search-engine optimization, and it refers to the process of optimizing a website for search engines. In simpler words, it refers to the process of improving your website in order to increase its visibility when people use Google, Bing, and other search engines to find what they’re looking for.

The best way to make your Blazor Server application SEO-friendly is to work on the title, meta description, and H1 tag in the _Host.cshtml common page or in individual pages based on your requirements and development activities. If you include keywords in the title, meta description, and H1 tag of your Blazor Server application, the app will appear near the top of search engine results when people search for general information using those keywords.

meta tags

Title: The title must be text-only and appears in the browser’s title bar or in the page’s tab.

meta title

H1 tag: The H1 tag will be displayed as the application’s top-level heading.

h1 tag

Meta description:  The meta description will be displayed as compressed content just below the search-related link.

meta description

Meta keywords: If anyone searches for a keyword mentioned in your Blazor application, the app will appear at the top of the search engine results. However, Googlebot no longer considers meta keywords to be SEO-friendly.

meta keywords

Note: Make sure that your title, H1 tag, and meta description are unique. If the description or title is too long, Google will limit the content to a specific range. Follow these guidelines to avoid unwanted content loss:

  • Title: should be between 20 and 70 characters long.
  • Meta description: should be between 100 and 160 characters long.
  • H1: should be between 20 and 70 characters long.
Permalink

Use HttpContext through the IHttpContextAccessor interface to get the user agent details in a Blazor Server application. The following example demonstrates how to use HttpContext to get the user agent and IP address details by default. Extend the AddHttpContextAccessor() method in the Program.cs file. 

[Program.cs]

builder.Services.AddHttpContextAccessor();

[Index.razor]

@page "/"
@using Microsoft.AspNetCore.Http
@inject IHttpContextAccessor httpContextAccessor

<p>UserAgent = @UserAgent</p>
<p>IPAddress = @IPAddress</p>

@code {
    public string UserAgent { get; set; }
    public string IPAddress { get; set; }

    protected override void OnInitialized()
    {
        UserAgent = httpContextAccessor.HttpContext.Request.Headers["User-Agent"];
        IPAddress = httpContextAccessor.HttpContext.Connection.RemoteIpAddress.ToString();
    }
}

Refer to this link for more details.

Permalink

Use the System.Timers.Timer class to wait until the user has finished typing in the text field. The onkeyup event triggers for each key press and resets the timer until the last timer raises the OnUserFinish event.

[Index.razor]

@page "/"
@using System.Timers;

<input type="text" @bind-value="dataValue" @bind-value:event="oninput" @onkeyup="@OnValueChange" />
<p>@Content</p>

@code {
    private string dataValue { get; set; }
    private string Content { get; set; }
    private Timer timerObj;

    protected override void OnInitialized()
    {
        timerObj = new Timer(1500);
        timerObj.Elapsed += OnUserFinish;
        timerObj.AutoReset = false;
    }

    private void OnValueChange(KeyboardEventArgs e)
    {
        // remove previous one
        timerObj.Stop();
        // new timer
        timerObj.Start();
    }

    private void OnUserFinish(Object source, ElapsedEventArgs e)
    {
        InvokeAsync(() =>
        {
            Content = $"Typed text: {dataValue}";
            StateHasChanged();
        });
    }
}

View Sample in GitHub

Permalink

In the following example, we’ve animated state transitions using CSS in a Blazor app.

When the state is changed, adding and removing the property values for every state transition is animated.

Create a separate reusable component (.razor) in the Pages folder and add the animation.

[Pages/AnimeState.razor]


<div class="container @(IsShown?"spin-in":"fade-out")">
    <span>@(Name??"")</span>
</div>

<style>
    .container{
        display:inline-block;
        width:@width;
        height:@height;
        color:white;
        background-color:blue;
    }

    .fade-out{
       animation: fade @AnimationTime linear forwards;
    }

    .spin-in{
       animation: spin @AnimationTime linear forwards;
    }

    @@keyframes fade {
      0%   {opacity:1;}
      99%  {width:@width; height:@height;}
      100% {width:0px;height:0px; opacity:0;}
    }

    @@keyframes spin {
      0%   {width:0px;height:0px; transform: rotate(0deg);}
      99%  {width:@width; height:@height;}
      100% {width:@width;height:@height;transform: rotate(1440deg);}
    }
</style>

@code {
    string width = "100px";
    string height = "20px";

    [Parameter] public string Name { get; set; }
    [Parameter] public string AnimationTime { get; set; }
    [Parameter] public bool IsShown { get; set; }
}

Add the AnimeState.razor component and define the property value to be animated when the state has been changed.

[Index.razor]

@page "/"

<button class="btn btn-primary" @onclick="OnButtonClick">Switch</button>
<AnimeState Name="Blazor" AnimationTime="2s" IsShown=@isShown />
<span>State transition Animation</span>
@code{
    bool isShown = true;

    private void OnButtonClick() 
    {
        isShown = !isShown;
    }
}

View Sample in GitHub

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 Program.cs file to create a consent cookie.

[Program.cs] 

builder.Services.Configure<CookiePolicyOptions>(options => 
{ 
    options.CheckConsentNeeded = context => true; 
    options.MinimumSameSitePolicy = SameSiteMode.None; 
}); 
builder.Services.AddHttpContextAccessor(); 
var app = builder.Build(); 
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 _Layout.cshtml/_Host.cshtml/index.cshtml file to store the cookie.

[_Layout.cshtml]/_Host.cshtml/index.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]

<main> 
	<div class="top-row px-4"> 
		<ConsentCookie /> 
    </div>   
	<article class="content px-4"> 
		@Body 
    </article> 
</main>

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.

View Sample in GitHub

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

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.

View Sample in GitHub

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 HTML content in client-side (browser). So, you can determine whether it is a Desktop, or a Mobile device based on the viewport’s width.

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.

Blazor app with responsive

Another way, you can create a responsive design using media queries that adjusts to the size of the user’s screen based on desktop or mobile browser.

For example, you define breakpoints for small, medium, and large screen sizes.  

<style>
    /* Default styles */ 
    @media (max-width: 576px) { 
        /* Styles for small screens */ 
    } 

    @media (min-width: 577px) and (max-width: 992px) { 
        /* Styles for medium screens */ 
    }  

    @media (min-width: 993px) { 
        /* Styles for large screens */ 
    } 
</style> 

For more details, refer to this link.

Permalink

To reconnect the Blazor server automatically you need to include the following code in the script of the Blazor application. This will refresh the Blazor server automatically when it is up again.

[_Host.cshtml]

<script>
   Blazor.defaultReconnectionHandler._reconnectCallback = function(d) {
        document.location.reload(); 
   }
</script>
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).

@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();
}

View Sample in GitHub

Permalink

To retrieve a selected value from the select control, you can use either the @bind or @onchange event.

//using @bind

@page "/dropdown"
<select class="form-control" @bind="@selectedString" style="width:150px">
         @foreach (var template in templates)
         {
                 <option value=@template>@template</option>
         }
</select>

<h5>Selected Country is: @selectedString</h5>

@code {
List<string> templates = new List<string>() { "America", "China", "India", "Russia", "England" };
string selectedString = "America";
    }
//using @onchange event

@page "/dropdown"

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

<h5>Selected Country is: @selectedString</h5>

@code {
List<string> templates = new List<string>() { "America", "China", "India", "Russia", "England" };
string selectedString = "America";

void OnSelect (ChangeEventArgs e)
{
        selectedString = e.Value.ToString();
        Console.WriteLine("The selected country is : " + selectedString);
}
    }

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.

[Program.cs]

using Blazored.LocalStorage; 
…
builder.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/ 

View Sample in GitHub

Permalink

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

1. Use direct 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" />

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

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

[script.js]

function includeCss(url) {

var element = document.createElement("link"); 
element.setAttribute("rel", "stylesheet"); 
element.setAttribute("type", "text/css"); 
element.setAttribute("href", url); 
document.getElementsByTagName("head")[0].appendChild(element); 

}

[Index.razor] 

@page "/" 
@inject IJSRuntime JSRuntime 
<h1>Blazor Application</h1> 

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

View Sample in GitHub

Permalink

You can get the current page title in Blazor by using the “title” property of the document object in JavaScript and by using a .JavaScript interop since there is no DOM accessibility in Blazor. The following example shows how to get the page name.

[script.js]

window.getTitle = () => { 
       return document.title; 
};
@page "/"

@inject IJSRuntime jsRuntime

<h2>Page Title: @Title</h2>

<button class="btn btn-primary" @onclick="@GetTitle">Get Title</button>


@code {

    public string Title = "";
    
    public async void GetTitle()
    {
            Title = await jsRuntime.InvokeAsync<string>("getTitle");
     }
}
Permalink

A query string stores values in the URL that are visible to users. It is mostly used to pass the data from one page to another. In Blazor, the query string can be added using the NavigationManager. You can pass multiple parameters through the URL and access it via queryhelpers,

1. Install the package Microsoft.AspNetCore.WebUtilities from NuGet.

2. Use the QueryHelpers.ParseQuery.TryGetValue method

@page "/queryparam"
@inject NavigationManager navManager

<h3>Query Paramter Demo</h3>
<div>Id = @Id</div>
<div>Name = @Name</div>
@code{
 string Id { get; set; }
 string Name { get; set; }
 protected override void OnInitialized()
  {
            GetId();
            GetName();
   }
                public void GetId()
 {
        var uri = new Uri(navManager.Uri);
        Id =       Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query).TryGetValue("id", out var type) ? type.First() : "";
        }
        public void GetName()
        {
            var uri = new Uri(navManager.Uri);
            Name = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(uri.Query).TryGetValue("name", out var type) ? type.First() : "";
        }
    }
Permalink

To perform the wait operation in Blazor, we need to use Task.Delay(Time in milliseconds) which will wait for the specified time before execution.

In the sample, we have delayed the count increment by a second by using the Task.Delay() method.

[counter.razor]
@page "/counter"

<h1>Counter</h1>

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

<button class="btn btn-primary" @onclick="@(async () => await Increment())">Click me</button>

@code {
private int currentCount = 0;

async Task Increment()
 {
        await Task.Delay(1000);
        currentCount++;
  }
}
Permalink

As of now, hot reload is not supported in Blazor, but it has been scheduled for the .NET 5 release. Please refer here for more information.

However, you can use the following command in the command prompt.

dotnet watch run debug 

Also, you must include the following file types in the .csproj file for which files you want to watch.

<DotNetCliToolReference Include="Microsoft.DotNet.Watcher.Tools" Version="2.0.0" />
<ItemGroup>
    <Watch Include="..\**\*.razor" />
    <Watch Include="..\**\*.scss" />
    <Watch Include="..\**\*.cs" />
</ItemGroup>

Reference Link: https://stackoverflow.com/questions/58172922/is-there-any-hot-reload-for-blazor-server-side

Permalink

We can define specific instances for custom components by using @ref while defining the component in a Razor file.

In this sample, we have created the component reference for the card components with specific names. Using this reference, we can access the card component properties and modify them. Here we have changed the display property using the component reference.

[Card.razor]
<div class="card mb-3 @display" style="width: 18rem;">
 <div class="card-body">
      @ChildContent
 </div>
</div>

@code {
    string display = "";

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

    public void setVisible(bool visible)
    {
        if (visible)
        {
            display = "";
        }
        else
        {
            display = "d-none";
        }
    }
}
[index.razor]

@page "/"

<Card @ref="MyCardControl1">First Card</Card>

<Card @ref="MyCardControl2">Second Card</Card>

<button class="btn btn-primary" @onclick="Hide">Hide card</button>
<button class="btn btn-primary" @onclick="Show">Show card</button>

<button class="btn btn-primary" @onclick="Hide2">Hide card2</button>
<button class="btn btn-primary" @onclick="Show2">Show card2</button>
@code {

    Card MyCardControl1;
    Card MyCardControl2;

    private void Hide()
    {
        MyCardControl1.setVisible(false);
    }
    private void Show()
    {
        MyCardControl1.setVisible(true);
    }

    private void Hide2()
    {
        MyCardControl2.setVisible(false);
    }
    private void Show2()
    {
        MyCardControl2.setVisible(true);
    }
}
Permalink

There is no direct way to detect whether the page is loaded on mobile or desktop in Blazor. We have to find out through the userAgent property from the JavaScript side using a JSInterop call. In order to find out, add a “script.js” file in the wwwroot folder and include the isDevice method call. You can then invoke the isDevice method to identify the correct device.

Refer to the following code for further details.

[wwwroot/script.js]

function isDevice() {
    return /android|webos|iphone|ipad|ipod|blackberry|iemobile|opera mini|mobile/i.test(navigator.userAgent);
}

Refer the script file in the HTML page

[index.html/_Host.cshtml]

<head>
 .....
 <script src="~/script.js"></script>
 ....
</head>
[index.razor]

@page "/"
@inject IJSRuntime jsRuntime

<h1>Responsive</h1>

<button @onclick="FindResponsiveness">Find Device</button>
<h2>@isDevice</h2>
@code {
    private string isDevice { get; set; }
    private bool mobile { get; set; }
    public async Task FindResponsiveness()
    {
        mobile = await jsRuntime.InvokeAsync<bool>("isDevice");
        isDevice = mobile ? "Mobile" : "Desktop";

    }
}

For more details about mobile browser detection, refer to this link.

Permalink

If you want to show a message using a simple browser alert message box, it is easy to do in Blazor. In Blazor, you can call a JavaScript method using JavaScript interop.

In the following code snippets, the text entered in the text box will be displayed in the alert box. In order to call the JavaScript method in Blazor, you should register the method in the browser window class. You can pass the message you want to show by passing method parameters in the JSRuntime.InvokeAsync method.

[script.js]
window. Alert = function(message) {
           alert(message);
}

Refer the script file in the HTML page

[index.html/_Host.cshtml]
<head>
 .....
 <script src="~/script.js"></script>
 ....
</head>
[index.razor]

@page "/"

<input type="text" @bind="message" />
<button class="btn btn-primary" @onclick="Alert"> Alert Me!</button>

@code {

string message = "";

    private async Task Alert()
    {
        await JSRuntime.InvokeAsync<object>("Alert", message);
    }
}
Permalink

You can redirect to a page in Blazor using the Navigation Manager’s NavigateTo method. In the following code snippet, it will redirect to the home page when this page gets loaded. Similarly, you can call NavigateTo() method from NavigationManager class anywhere to redirect to another page.

Refer to the following code snippet.

@page "/redirect"
@inject NavigationManager NavManager

<h1>Redirect Page</h1>

<p>Redirecting to Default Page</p>

@code {
    protected override void OnInitialized()
    {
        NavManager.NavigateTo("/");
    }
}
Permalink

A URL can be opened in a new tab either by using the NavLink component or by using JavaScript. In the NavLink component, we can specify the URL to be opened in a new tab in the href parameter. In interop’s IJSRuntime instances, the method InvokeAsyncwith parameters open, URL, and _blank are used. Here, the third parameter, _blank, is used to notify that the URL needs to be opened in the new tab.

@inject IJSRuntime jsRuntime

<NavLink href="/counter">Open</NavLink> 
<button @onclick="NavigateToNewTab">New Tab Navigation</button>

@code {

    public async Task NavigateToNewTab()
    {
        string url = "/counter";
        await jsRuntime.InvokeAsync<object>("open", url, "_blank");
    }
}
Permalink

You can change the default icon provider for Blazor by importing the required icons in the site.css (\wwwroot\css\site.css or app.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/app.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, I have changed the default icons to the Material icons for the home page and counter. 

Permalink

In Blazor, you can retrieve the IP address of the current request by utilizing the IHttpContextAccessor service. To do this, 

  1. Add builder.Services.AddHttpContextAccessor in your Program.cs file. 
  2. Then, inject IHttpContextAccessor into your component or service where you require the IP address. 
  3. Finally, obtain the client’s IP address using HttpContext.Connection.RemoteIpAddress
@page "/" 
@using Microsoft.AspNetCore.Http 
<h3> Here's an example of how to retrieve the IP address from HttpContext in Blazor</h3> 
<p>Localhost IP address: @ipAddress</p> 

@code { 
    private string? ipAddress; 
    [Inject] 
    private IHttpContextAccessor? httpContextAccessor { get; set; } 
    protected override void OnInitialized () 
    { 
        ipAddress = httpContextAccessor?.HttpContext?.Connection?.RemoteIpAddress?.ToString(); 
    } 
} 
Permalink

To load a dialog on demand in Blazor, we can create a modal dialog with a conditional attribute (@if). We can load the dialog in the HTML page by using the conditional attribute, which will render based on the Boolean property.
In the following code, we render the dialog on a button-click event in which the ShowPopup property will be set as true and the dialog will be shown on the page. We can remove the dialog by setting the ShowPopup property as false.

[index.razor]

@page "/"

@using BlazorApp.Data
@inject WeatherForecastService ForecastService

<h3>Dialog</h3>
<button class="btn btn-primary"
        @onclick="OpenDialog">
    Open Dialog
</button>
@if (ShowPopup)
{
    <!-- This is the popup to create or edit a forecast -->
    <div class="modal" tabindex="-1" style="display:block" role="dialog">
        <div class="modal-dialog">
            <div class="modal-content">
                <div class="modal-header">
                    <h3 class="modal-title">Modal Dialog</h3>
                    <!-- Button to close the popup -->
                    <button type="button" class="close"
                            @onclick="ClosePopup">
                        <span aria-hidden="true">X</span>
                    </button>
                </div>
                <!-- Edit form for the current forecast -->
                <div class="modal-body">
                    <input class="form-control" type="text"
                           placeholder="Celsius forecast"
                           @bind="forecasts[0].TemperatureC" />
                    <input class="form-control" type="text"
                           placeholder="Summary"
                           @bind="forecasts[0].Summary" />
                    <br />
                    <!-- Button to save the forecast -->
                    <button class="btn btn-primary"
                            @onclick="Save">
                        Save
                    </button>
                </div>
            </div>
        </div>
    </div>
}
@code {

    private WeatherForecast[] forecasts;

    protected override async Task OnInitializedAsync()
    {

        forecasts = await ForecastService.GetForecastAsync(DateTime.Now);
    }
    bool ShowPopup = false;
    void OpenDialog()
    {
        // Open the Popup
        ShowPopup = true;
    }
    void ClosePopup()
    {
        // closes the Popup
        ShowPopup = false;
    }
    void Save()
    {
        //closes dialog after the save execution
        ShowPopup = false;
    }
}
Permalink

We can focus an InputText Blazor element not directly but by using JavaScript in Blazor. We can set an ID for the InputText and then pass it to JavaScript using interop by method InvokeVoidAsync. In the JavaScript function, use the focus DOM input method for focusing the input element with the received ID from Blazor.

Refer to the following code snippet.

[script.js]
function focusInput(id) {
    document.getElementById(id).focus();
}

Refer the script file in the HTML page

[index.html/_Host.cshtml]
<head>
 .....
 <script src="~/script.js"></script>
 ....
</head>
[Index.razor]

@page "/"

@inject IJSRuntime jsRuntime

<EditForm Model="@inputText">
    <InputText id="@InputID" @bind-Value="inputText.TextValue">You can enter some text...</InputText>
</EditForm>

<br />
<br />

<button @onclick="Focus">FOCUS!!!</button>

@code {

    public string InputID = "input-id";
    public string Output = "";

    public class InputTextClass
    {
        public string TextValue = "Some Random Text";
    }

    public InputTextClass inputText = new InputTextClass();

    public async Task Focus()
    {
        await jsRuntime.InvokeVoidAsync("focusInput", InputID);
    }
}
Permalink

We can change a C# property’s value in Blazor from JavaScript by invoking the method DotNet.invokeMethodAsync in the script file (.js file). It takes the parameters Assembly name (Application name), the method name (public static method), and method parameter where we can change the C# static parameter.

Refer to the following code snippet for more details.

[script.js]

function ChangeContentJS() {
    DotNet.invokeMethodAsync('InvokeFromJsApp', "ChangeParaContentValue", "New Content");
}

Refer the script file in the HTML page

[index.html/_Host.cshtml]
<head>
 .....
 <script src="~/script.js"></script>
 ....
</head>
[Index.razor]

@page "/"

@inject IJSRuntime JSRuntime

<h1>Change C# property value from JavaScript</h1>
<br />
<button @onclick='ButtonClickHandler'>Change Content - JS</button>
<br />
<p>@ParaContent</p>

@code {
    public static string ParaContent = "Some Text Content";
    public async Task ButtonClickHandler()
    {
        await JSRuntime.InvokeAsync<string>("ChangeContentJS");
    }

    [JSInvokable]
    public static void ChangeParaContentValue(string value)
    {
        ParaContent = value;
    }
}

In the previous example, we have changed the ParaContent C# field value from the JavaScript by calling the static method ChangeParaContentValue from JavaScript, along with the new value as one of parameters in invokeMethodAsync.

  • The C# method should be defined as static and it should have a JSInvokable attribute.
  • The arguments in the JavaScript method Dotnet.invokeMethodAsync should be
    • InvokeFromJsApp—AssemblyName.
    • ChangeParaContentValue—C# JSInvokable static method name.
    • “New Content”—method arguments.

You can download the reference sample here.

Permalink

Blazor does not have support to manipulate DOM elements directly, but we can still achieve it by using JavaScript interop. By creating a reference to an element, we can send it as a parameter to the JavaScript method via interop. In that JavaScript method, we can manipulate the DOM elements.

[script.js]
window.setElementText = (element, text) => {
    console.log(element);
    element.innerText = text;
}

Refer the script file in HTML page

[index.html/_Host.cshtml]
<head>
 .....
 <script src="~/script.js"></script>
 ....
</head>
[Counter.razor]

@page "/counter"

@using Microsoft.JSInterop
@inject IJSRuntime JSRuntime

<h1>Counter</h1>

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

<p>Last button clicked: @lastButtonClicked</p>

<button @ref=button1 class="btn btn-primary" @onclick="@(()=>IncrementCount(@button1))">Click me</button>
<button @ref=button2 class="btn btn-primary" @onclick="@(()=>IncrementCount1(@button2))">Click me</button>


@code {

    private ElementReference button1;
    private ElementReference button2;

    private int currentCount = 0;
    private string lastButtonClicked = "None";

    private async void IncrementCount(ElementReference element)
    {
        currentCount++;
        lastButtonClicked = "Button 1";
        await JSRuntime.InvokeVoidAsync("setElementText", element, "Button 1 was clicked");

    }
    private async void IncrementCount1(ElementReference element)
    {
        currentCount++;

            lastButtonClicked = "Button 2";
            await JSRuntime.InvokeVoidAsync("setElementText", element, "Button 2 was clicked");
    }
}
Permalink

You can perform routing without changing the URL with the help of NavigationManager. You need to inject NavigationManager to use this service. You can use this service to perform routing programmatically.

Service Injection

@inject NavigationManager Navigate

<button @onclick="NavigateTo">Navigate</button>

@code {

      private void NavigateTo(){
             Navigate.NavigateTo("url");//specify required url here
      }
}
Permalink

We can handle the 404 error for query string parameters by checking whether the query is available in the parameter. If the parameter is not found, we can handle the error. We can also log an exception in Visual Studio by using the service ILogger in the application.

[Product.razor]
@page "/product-details/{ProductId:int}"
@using Microsoft.Extensions.Logging
@inject ILogger<ProductDetails> Logger

@if (details != null)
{
<h1>@details.ProductId</h1>
 <p>@details.Products</p>
}
else if (loadFailed)
{
    <h1>Product ID:@ProductId not found. Sorry, we could not load this product due to an error. Click <a href="/product-details/1001">here</a> to go back to first product page</h1>
    
}
else
{
  <h1>Loading...</h1>
}

@code {
    [Parameter] public int ProductId { get; set; }

    ProductDetails details;
    bool loadFailed;

    public List<ProductDetails> Data { get; set; }
    static ProductDetails Product_Details = new ProductDetails();

    protected override async Task OnParametersSetAsync()
    {
        try
        {
            loadFailed = false;
            details = await Product_Details.GetProductId(ProductId);
        }
        catch (Exception ex)
        {
            loadFailed = true;
            Logger.LogWarning(ex, "Failed to load product {ProductId}", ProductId);
        }
    }
    public class ProductDetails
    {
        public int ProductId { get; set; }
        public int In_Stock { get; set; }
        public int Sold { get; set; }
        public double Amount { get; set; }
        public string Country { get; set; }
        public string Product_Categories { get; set; }
        public string Products { get; set; }
        public string Order_Source { get; set; }
        public string Year { get; set; }
        public string Quarter { get; set; }

        public async Task<ProductDetails> GetProductId(int id)
        {
            List<ProductDetails> Product_Data = new List<ProductDetails>();
            Product_Data.Add(new ProductDetails { ProductId = 1001, In_Stock = 34, Sold = 51, Amount = 383, Country = "France", Product_Categories = "Accessories", Products = "Bottles and Cages", Order_Source = "Retail Outlets", Year = "FY 2015", Quarter = "Q1" });
            Product_Data.Add(new ProductDetails { ProductId = 1002, In_Stock = 4, Sold = 423, Amount = 3595.5, Country = "France", Product_Categories = "Accessories", Products = "Bottles and Cages", Order_Source = "Sales Person", Year = "FY 2015", Quarter = "Q1" });
            Product_Data.Add(new ProductDetails { ProductId = 1004, In_Stock = 38, Sold = 234, Amount = 1813.5, Country = "France", Product_Categories = "Accessories", Products = "Bottles and Cages", Order_Source = "Teleshopping", Year = "FY 2015", Quarter = "Q1" });
            Product_Data.Add(new ProductDetails { ProductId = 1005, In_Stock = 42, Sold = 127, Amount = 952.5, Country = "France", Product_Categories = "Accessories", Products = "Bottles and Cages", Order_Source = "App Store", Year = "FY 2015", Quarter = "Q1" });
            Product_Data.Add(new ProductDetails { ProductId = 1005, In_Stock = 36, Sold = 89, Amount = 668, Country = "France", Product_Categories = "Accessories", Products = "Bottles and Cages", Order_Source = "Retail Outlets", Year = "FY 2015", Quarter = "Q2" });
            if (id == Product_Data[0].ProductId)
            {

                return Product_Data[0];
            }
            else if (id == Product_Data[1].ProductId)
            {

                return Product_Data[1];
            }
            else if (id == Product_Data[2].ProductId)
            {

                return Product_Data[2];
            }
            else if (id == Product_Data[3].ProductId)
            {

                return Product_Data[3];
            }
            else if (id == Product_Data[4].ProductId)
            {

                return Product_Data[4];
            }
            else if(id == Product_Data[5].ProductId)
            {
                return Product_Data[5];
            }

            return null;
        }
    }
}

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

You can capture input keyboard events by attaching the event handler to the keyboard events such as Keydown, Keypress, or Keyup with the input control. In the following example, the keyboard event handler is attached to all these three events. If you want to identify which keyboard event is captured, you can get the type using the KeyboardEventArg.Type property.

[index.razor]

@page "/"

<input type="text" @onkeydown="KeyboardEventHandler " @onkeypress=" KeyboardEventHandler " @onkeyup="KeyboardEventHandler "/>

<h4>@KeyPressed </h4>
<h4>@EventInfo</h4>

@code {
    string KeyPressed = "";
    string EventInfo = "";
    private void KeyboardEventHandler(KeyboardEventArgs args)
    {
        KeyPressed = "Key Pressed is " + args.Key;
        EventInfo = "Event Type " + args.Type;
    }
}
Permalink

After the database is updated, StateHasChanged method can be called to refresh the page/UI. When called, this will rerender the component or the page based on the new changes from the database. 

Razor File

@page "/counter"  
<PageTitle>Counter</PageTitle>  
<h1>Counter</h1>  

<p role="status">Current count: @CurrentCount</p>  

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

@code {  
	[Parameter]  
    public int CurrentCount { get; set; } = 0;  

    private async Task IncrementCount ()  
    {  
        CurrentCount++;  
        await InvokeAsync(StateHasChanged);  
    }  
}
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. 

Razor file 

@page "/" 
<input type="text" @bind="@message" /> 

@code{ 
    private string? message { get; set; } 
    protected override async Task OnAfterRenderAsync ( bool firstRender ) 
    { 
        // Perform any asynchronous operations after the component has been rendered 
        if (firstRender) 
        { 
            message = "Component rendering finished"; 
            await Task.Yield(); // Ensure the UI rendering is complete 
            StateHasChanged(); // Trigger UI update 
        } 
    } 

    protected override void OnAfterRender ( bool firstRender ) 
    { 
        // Perform any synchronous operations after the component has been rendered 
        Console.WriteLine("Component rendering completed"); 
        base.OnAfterRender(firstRender); 
    } 
} 
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() 
        => StartTimerAsync(); 
}
Permalink

Blazor provides support for suppressing events of the HTML DOM element in two ways

  • Suppressing default event
  • Suppressing event propagation

Suppressing default event:                                                                                                                        

The default events of the HTML DOM element can be suppressed by using the @on{Event}:preventDefault directive attribute provided in Blazor. This is useful in scenarios like suppressing the on key press event of an input text box.

<input type="text" @onkeypress:preventDefault />

You can also add your own event listener as done for event handling.

<input type="text" @onkeypress="EventHandlerMethod" @onkeypress:preventDefault />

Supressing event propagation:

HTML DOM element’s events tend to propagate some events to their parent element and then its parent element, and so on. Blazor provides support to supress the event propagation using the @on{EVENT}:stopPropagation directive attribute. This takes a Boolean variable as the input. This is visualized as follows.

<button @onclick:stopPropagation="true">Click</button>

As the stopPropagation attribute which takes the value of a Boolean variable can be bound to a property, the propagation can be stopped based on the user requirement.

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

You can call JavaScript methods from the Blazor pages with the help of JavaScript Interop by injecting the dependency IJSRuntime into the razor page.

[script.js]
function buttonClick() {
    // this function triggers on button click
}

Then refer the script in the HTML page of the blazor application.

<script src="~/script.js"></script>
[index.razor]
@page "/"
@inject IJSRuntime jsRuntime

<button @onclick="onbuttonclick"> Button  </button>

@code {
    protected void onbuttonclick (MouseEventArgs args)
    {
        await jsRuntime.InvokeVoidAsync<object>("buttonClick ");
    }
}

Check this link for more information.

Permalink

To debug a client-side Blazor app in a browser:

  1. Close the all instances in Chrome.
  2. Run the Blazor app in Chrome (version 70 or later).
  3. Open Win + R and run following command.
"%programfiles(x86)%\Google\Chrome\Application\chrome.exe"   --remote-debugging-port=9222 http://localhost:52902/
  • Now the Blazor app is running.
  • Then hit Shift+Alt+D on Windows or Linux and Shift+Cmd+D on macOS.

Reference link:

https://docs.microsoft.com/en-us/aspnet/core/blazor/debug?view=aspnetcore-3.1

https://www.hanselman.com/blog/CompilingCToWASMWithMonoAndBlazorThenDebuggingNETSourceWithRemoteDebuggingInChromeDevTools.aspx

Permalink

There are two methods to call a method from JavaScript:

  • DotNet.invokeMethod
  • DotNet.invokeMethodAsync

The syntax of calling a C# method from JavaScript is as follows.

DotNet.invokeMethodAsync('C# method assembly name', 'C# Method Name');

Add the .NET function invoke statement to a script in the head of Pages/_Host.cshtml file.

<script>
   function CSMethod() {
      DotNet.invokeMethodAsync('BlazorTestApp', 'CSCallBackMethod');
   }
</script>

Here we are defining a JavaScript function “CSMethod”. This function will have a callback to our .NET function “CSCallBackMethod” which is defined in index.razor.

To invoke C# method from JavaScript,

  • The method must be decorated with “JSInvokable” attribute.
  • The method must be public.
  • The method may either be static or instance-level (this is only supported by Blazor 0.5.0 and above).
  • The Identifier for the method must be unique.
  • The method must be nongeneric.
@page "/jsinterop"
@inject IJSRuntime JsRuntime;

<button @onclick="WriteToConsole">Call .NET Method</button>
<br />
<p>@message</p>


@code {
    protected static string message { get; set; }

    [JSInvokable]
    public static void CSCallBackMethod()
    {
        message = "C# Method invoked";
    }

    private async Task WriteToConsole()
    {
        await JsRuntime.InvokeAsync<object>("CSMethod");
    }
}

Reference LinkReference link

https://www.freecodecamp.org/news/how-to-implement-javascript-interop-in-blazor-9f91d263ec51/

Permalink

Currently, Blazor doesn’t provide any direct way to access the browser’s DOM or APIs. But there is an option to invoke/call JavaScript functions via JS Interop, thereby letting Blazor access the DOM and its APIs. In the below example we have accessed the button’s DOM element in the script by using javascript interop.

[_Host.cshtml/index.html]

<script>
function accessDOMElement() {
    var btn;
    // access DOM here
    btn = document.getElementById('btn');
    btn.innerText = "Button Textchanged";
}
</script>
[index.razor]

@page "/"
@inject IJSRuntime jsRuntime

<h1>@Title</h1>

<button id="btn" @onclick="UpdateTitle">Update Title</button>

@code {
    private string Title { get; set; } = "Hello, World!";

    private async void UpdateTitle()
    {
        await jsRuntime.InvokeAsync<object>("accessDOMElement");
        Title = "Hello, Blazor!";
    }
}
Permalink

Inject NavigationManager in razor.

@inject NavigationManager NavigationManager

Use Uri from NavigationManager to get the current URL.

string currentUrl = NavigationManager.Uri;

Sample code

@page "/sample"
@inject NavigationManager NavigationManager

<p>@currentUrl</p>

@code {
    private string currentUrl;

    protected override void OnInitialized()
    {
        currentUrl = NavigationManager.Uri;
    }
}
Permalink

You can use the following CSS classes to apply your own styles to validation messages.

CSS class name Added DOM element 
valid/invalid Added to the <input> element of DOM 
validation-errors  Added to the dynamically created <ul>
element while using the
<ValidationSummary> tag 
validation-message Added to the dynamically created <div> / <li>
element which holds to error message. 

<div> – created while using
<ValidationMessage> tag 
<li> – created while using
<ValidationSummary> tag 
modified Added to the <input> element after modifying the default value. 
Permalink

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

[Razor Page]

@page "/" 

@inject IJSRuntime JSRuntime 
<p>Here created cookies</p> 
<button onclick="@(() => CreateCookie("myCookie", "myValue", 7))">Create Cookie</button> 

@code { 

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

[index.html]

<body> 
    …. 
    <script > 
        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=/"; 
            } 
        } 
    </script> 
</body> 

View Sample in GitHub

Permalink

You have to define and bind the EditContext with EditForm and then call the method editContext.Validate() on button click to manually trigger the validation.

@using System.ComponentModel.DataAnnotations;

<EditForm EditContext="@EC">
    <DataAnnotationsValidator />
    <ValidationSummary />
    <div class="form-group d-flex justify-content-between">
        <label class="col-form-label col-3" for="name">Time</label>
        <InputText bind-Value="@model.Name" id="name" Class="form-control" />
    </div>
    <button type="button" onclick="@SubmitHandler" class="btn btn-primary">Submit</button>
</EditForm>
@code {
    public class ModelClass
    {
        [Required]
        public string Name { get; set; }
    }
    private ModelClass model { get; set; } = new ModelClass { Name = "" };
    private EditContext EC { get; set; }
    protected override void OnInitialized()
    {
        EC = new EditContext(model);
        base.OnInitialized();
    }
    private void SubmitHandler()
    {        
        EC.Validate(); // manually trigger the validation here
    }
}
Permalink

DOM elements are hidden using the hidden attribute. You can conditionally use any .NET parameter to set this attribute to hide the DOM elements.

@page "/"
    
   <p hidden="@IsShow">I am Blazor</p>
    
   <button @onclick="@Show">Show/Hide</button>
  
 @code {
       private bool IsShow   {get;set;} = false;
       private void Show()
       {
           IsShow =   !IsShow;
       }      
 } 
Permalink

DOM attributes are rendered based on .NET parameters. If the parameter value is true, the attribute is rendered minimized, otherwise it’s not. Refer to the code example to render the checked attribute conditionally.

 <input type="checkbox" checked="@IsChecked">
  
 @code {
     [Parameter]
     public bool IsChecked { get; set; }
 } 
Permalink

To check if a browser supports WebAssembly, you can use the following code snippet in JavaScript: 

<script> 
        if (typeof WebAssembly !== 'undefined') { 
        // WebAssembly is supported 
        console.log(' WebAssembly is supported') 
        } else { 
        // WebAssembly is not supported 
        console.log('WebAssembly is not supported') 
        } 
</script> 
Permalink

Share with

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

Please submit your question and answer.