Live Chat Icon For mobile
Live Chat Icon

Blazor FAQ

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

Blazor allows JavaScript isolation in standard JavaScript modules. JavaScript isolation provides the following benefits:

  • JavaScript code is allowed to load only specified components.
  • Imported JavaScript does not affect any global namespace.
  • Library and component consumers are not required to import the related JavaScript.
Follow these steps to implement JavaScript isolation in Blazor:

  1. Create an export JavaScript function in the wwwroot/script folder.
    [isolationScript.js]

    export function jsIsolation(value) {
        console.log(value);
    }

  2. Import the JavaScript function using the IJSRuntime.InvokeAsync method in Blazor and call the JavaScript method on button click event.
    [Index.razor]

    @page "/"
    @inject IJSRuntime JSRuntime
     
    Enter text:<input @bind="content" />
    <button class="btn btn-primary" @onclick="OnClickButton">Click</button>
     
    @code {
        private string content { get; set; }
     
        private async void OnClickButton()
        {
            var jsModule = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./script/isolationScript.js"); 
            await jsModule.InvokeVoidAsync("jsIsolation", content);
        }
    }
    The JavaScript code file loads only during a button click event. It will not load again and again for each button click. 

    Refer to this documentation for more details.

Permalink

Using JavaScript onmousemove and onkeypress events to trigger the Timer function in a Razor component can identify whether a user is active or inactive. If the user has not performed any onmousemove or onkeypress events, the user is considered in an inactive state and the Timer function is called after certain TimeInterval to log the user out.

Follow these steps to log the user out automatically if they’re not active:

  1. Call the onmousemove and onkeypress properties in a JavaScript function to fire the Timer function in the Razor component.
    [_Host.cshtml]

    <body>
        // . . .
        <script>
            function timeOutCall(dotnethelper) {
                document.onmousemove = resetTimeDelay;
                document.onkeypress = resetTimeDelay;
     
                function resetTimeDelay() {
                    dotnethelper.invokeMethodAsync("TimerInterval");
                }
            }
        </script>
    </body>

  2. Now call the Timer method to identify whether the user is active or not. Add navigation to the logout action when the user is inactive.
    [MainLayout.razor]

    @using System.Timers
    @inject NavigationManager UriHelper
    @inject IJSRuntime JSRuntime
     
    // . . .
    @code {
        [CascadingParameter]
        private Task<AuthenticationState> stateAuthenticate { get; set; }
        private Timer timerObj;
     
        protected override async Task OnInitializedAsync()
        {
            // Set the Timer delay.
            timerObj = new Timer(7000);
            timerObj.Elapsed += UpdateTimer;
            timerObj.AutoReset = false;
            // Identify whether the user is active or inactive using onmousemove and onkeypress in JS function.
            await JSRuntime.InvokeVoidAsync("timeOutCall", DotNetObjectReference.Create(this));
        }
     
        [JSInvokable]
        public void TimerInterval()
        {
            // Resetting the Timer if the user in active state.
            timerObj.Stop();
            // Call the TimeInterval to logout when the user is inactive.
            timerObj.Start();
        }
     
        private void UpdateTimer(Object source, ElapsedEventArgs e)
        {
            InvokeAsync(async() => {
                // Log out when the user is inactive.
                var authstate = await stateAuthenticate;
                if (authstate.User.Identity.IsAuthenticated)
                {
                    UriHelper.NavigateTo("logout", true);
                }
            });
        }
    }

Permalink

To get a browser’s culture in Blazor WebAssembly, call the (navigator.language) property in JavaScript using the JavaScript interop function in Blazor. It will return the current browser’s language version.

Follow this code to get the browser’s culture in Blazor WebAssembly.

[Index.razor]

@page "/"
@inject IJSRuntime JSRuntime

@code{
    protected override async Task OnInitializedAsync()
    {
        var browserLanguage = await JSRuntime.InvokeAsync<string>("getBrowserLanguage");
        Console.WriteLine(browserLanguage);
    }
}

[index.html]

<body>
      . . .
      . . .
   <script>

      window.getBrowserLanguage = function () {
            return (navigator.languages && navigator.languages.length) ? navigator.languages[0] :
                navigator.userLanguage || navigator.language || navigator.browserLanguage || 'en';
        }  
        
   </script>
</body>
Permalink

To convert the date and time to a client’s or user’s time zone in Blazor Server, use the JavaScript function to get the current offset time difference from UTC in minutes using the new Date().getTimezoneOffset() method in Blazor using JavaScript Interop. Display the local time by the current offset time difference.
Follow these steps to convert the server time zone to the user’s time zone.

  1. Add the JavaScript function using JS Interop. Get the current offset time from UTC in minutes using the new Date().getTimezoneOffset() method.
    [_Host.razor]

    <body>
         @*Requires render-server mode as "Server" while initializing the component to execute JavaScript in OnInitializedAsync.*@
         <component type="typeof(App)" render-mode="Server" />
          . . . 
          . . . 
     
       <script>
            function GetTimezoneValue() {
                // Returns the time difference in minutes between UTC time and local time.
                return new Date().getTimezoneOffset();
            }
        </script>
    </body >

  2. Now display the UTC time and calculate the user time by using the offset time difference.
    [Index.razor]

    @page "/"
    @inject IJSRuntime JsRuntime
    <h1>Current DateTime</h1>
     
    <p>Now (UTC): @DateTimeOffset.UtcNow.ToString()</p>
    <p>Now (local): @localTime.ToString()</p>
     
    @code {
        private DateTimeOffset localTime;
        private TimeSpan? userTime;
     
        protected override async Task OnInitializedAsync()
        {
            if (userTime == null)
            {
                int timeDiffer = await JsRuntime.InvokeAsync<int>("GetTimezoneValue");
                userTime = TimeSpan.FromMinutes(-timeDiffer);
            }
     
            // Converting to local time using UTC and local time minute difference.
            localTime = DateTimeOffset.UtcNow.ToOffset(userTime.Value);
        }
    }
    Refer to this link for more details.

Permalink

To get the current data and time from client, use the date object (new Date()) in JavaScript using JavaScript Interop. It will return the browser’s date and time. Following is the code to get the current date and time from the client in Blazor WebAssembly.

[Index.razor] 

@page "/" 
@inject IJSRuntime JsRuntime 
 
<p id="date-time"></p> 
 
@code { 
    protected async override Task OnAfterRenderAsync(bool firstRender) 
    { 
        if (firstRender) 
        { 
            await JsRuntime.InvokeVoidAsync("GetDateTime"); 
        } 
    } 
} 

[index.html]

<body>  
      . . .  
      . . .  
 
   <script> 
        function GetDateTime() { 
           // Date object will return browser's date and time by default in JavaScript. 
           document.getElementById("date-time").innerHTML = new Date(); 
        } 
    </script> 
</body >
Permalink

Google reCaptcha is a process that helps to protect websites form spam and abuse. To implement Google reCaptcha in Blazor, refer to the Google reCaptcha script link the WebAssembly app and render the reCaptcha by calling the JavaScript function.
Follow these steps to implement Google reCaptcha in Blazor WebAssembly.

  1. Add the Google reCaptcha renderer function in a separate JavaScript file under the wwwroot folder.
    [googlereCaptcha.js]

    function googleRecaptcha(dotNetObject, selector, sitekeyValue) {
        return grecaptcha.render(selector, {
            'sitekey': sitekeyValue,
            'callback': (response) => { dotNetObject.invokeMethodAsync('CallbackOnSuccess', response); },
            'expired-callback': () => { dotNetObject.invokeMethodAsync('CallbackOnExpired', response); }
        });
    };
     
    function getResponse(response) {
        return grecaptcha.getResponse(response);
    }

  2. Add the reCaptcha script link and reference the reCaptcha.js file source in index.html.
    [index.html]

    <body> 
          . . . 
          . . . 
     
       <script src="googlereCaptcha.js"></script>
       <!-- reCaptcha rendering script -->
       <script src="https://www.google.com/recaptcha/api.js"></script>
    </body >

  3. Now call the rendering reCaptcha function in JavaScript from the Razor page using JavaScript Interop and show the reCaptcha response on button click.
    Note: To start using reCaptcha, you need to generate the API site key for your site. Refer to this link to generate the site key.
    [Index.razor]  

    @page "/"
    @inject IJSRuntime JSRuntime
    @using System.ComponentModel
     
    <h3>Google reCAPTCHA</h3>
     
    <div id="google_recaptcha "></div>
     
    <button class="btn btn-primary" @onclick="ShowResponse">Show Response</button>
     
    <br />
     
    <p>@captchaResponse</p>
     
    @code {
        private string captchaResponse;
     
        protected override async Task OnAfterRenderAsync(bool firstRender)
        {
            if (firstRender)
            {
                await JSRuntime.InvokeAsync<int>("googleRecaptcha", DotNetObjectReference.Create(this), "google_recaptcha ", "your-sitekey");
            }
            await base.OnAfterRenderAsync(firstRender);
        }
     
        [JSInvokable, EditorBrowsable(EditorBrowsableState.Never)]
        public void CallbackOnSuccess(string response)
        {
            captchaResponse = response;
        }
     
        [JSInvokable, EditorBrowsable(EditorBrowsableState.Never)]
        public void CallbackOnExpired(string response)
        {
            //...
        }
     
     
        private void ShowResponse()
        {
            captchaResponse = $"The response for the Google reCAPTCHA widget: {captchaResponse}";
        }
    }



Permalink

You call a JavaScript function with parameters using JavaScript Interop.

Syntax:

JsRuntime.InvokeVoidAsync("JS method name", "parameters");

Follow this code to call a JavaScript method with parameters in Blazor WebAssembly

[Index.razor]

@page "/"
@inject IJSRuntime JsRuntime

@code {
    protected override async void OnInitialized()
    {
        string content = "JavaScript function called with parameter";
        await JsRuntime.InvokeVoidAsync("jsFunction", content);
    }
}

[index.html]

<body> 
      . . . 
      . . . 

   <script>
        function jsFunction(value) {
            // Parameter value has been passed here.
            console.log(value);
        };
    </script>
</body >

Refer to this documentation for more information.

Permalink

Close a browser window from a page in Blazor WebAssembly using JavaScript Interop with the window.close() method. The window.close() method closes the currently opened window.

In the following example, open a new browser window and close it using the window.close() method with a button onclick event.

[Index.razor]

@page "/"
@inject IJSRuntime JsRuntime

<button @onclick="@(e => OnButtonClick("open"))">Open Window</button>
<button @onclick="@(e => OnButtonClick("close"))">Close Window</button>

@code {        
    private void OnButtonClick(string value)
    {
        JsRuntime.InvokeVoidAsync($"window.{value}");
    }
}
Permalink

Get a user agent in Blazor WebAssembly using JavaScript Interop with the navigator.userAgent property.

[Index.razor]

@page "/"
@inject IJSRuntime JsRuntime

<p>@userAgent</p>

@code {

    private string userAgent { get; set; }

    protected override async Task OnInitializedAsync()
    {
        userAgent = await JsRuntime.InvokeAsync<string>("getUserAgent");
        
    }
}

[index.html]

<body> 
      . . . 
      . . . 
   <script>
        window.getUserAgent = () => {
            return navigator.userAgent;
        };
    </script> 
</body > 
Permalink

Window dimension values are read using JavaScript Interop with the window.innerHeight and window.innerWidth properties.
Follow these steps to get the window dimension value in Blazor WebAssembly.

[Index.razor]

@page "/"
@inject IJSRuntime JsRuntime

<h1>Window Dimensions</h1>

<button class="btn btn-primary" @onclick="OnButtonClick">Get Dimensions</button><br /><br />

<p>Window Height: @Height</p>
<p>Window Width: @Width</p>

@code {

    public int Height { get; set; }
    public int Width { get; set; }

    private async Task OnButtonClick()
    {
        var dimension = await JsRuntime.InvokeAsync<WindowDimension>("getWindowDimensions");
        Height = dimension.Height;
        Width = dimension.Width;
    }

    public class WindowDimension
    {
        public int Width { get; set; }
        public int Height { get; set; }
    }

}

[index.html]

<body> 
      . . . 
      . . . 
 
   <script> 
        window.getWindowDimensions = function () {
            return {
                width: window.innerWidth,
                height: window.innerHeight
            };
        }; 
    </script> 
</body >
Permalink

DotNet.invokeMethod and DotNet.invokeMethodAsync are used to call C# methods with parameters from JavaScript in Blazor WebAssembly.

Syntax to call C# from JavaScript: 

DotNet.invokeMethodAsync(“C# method assembly name”, “C# method name”, “C# method parameter”); 

[Index.razor]

@page "/"
@inject IJSRuntime JsRuntime;

<button class="btn btn-primary" @onclick="OnButtonClick">Call C# from JS</button><br /><br />

<p>@content</p>

@code {
    private static string content { get; set; }

    [JSInvokable] // Return call back from JavaScript with parameter to C#.
    public static void JStoCSCall(string value)
    {
        content = value;
    }

    private async Task OnButtonClick() // Invoked by button clicking and calls JavaScript function.
    {
        await JsRuntime.InvokeAsync<object>("invokeJSfromCS");
    }
}

[index.html]

<body> 
      . . . 
      . . . 
 
   <script> 
        Function invokeJSfromCS () { 
            var value = "C# Method called from JavaScript with parameter";
            // Invoke to call C# function from JavaScript with parameter.
            DotNet.invokeMethod('BlazorWasmApp', 'JStoCSCall', value); 
        } 
    </script> 
</body >

Refer to this documentation 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.

Permalink

A Blazor app can invoke JavaScript functions from .NET methods and .NET methods from JavaScript functions. These scenarios are called JS interop.

There are two methods to call a C# method from JavaScript.

  1. DotNet.invokeMethod
  2. DotNet.invokeMethodAsync

Syntax to call C# from JavaScript:

DotNet.invokeMethodAsync(“C# method assembly name”, “C# method name”);

To call a C# method from JavaScript,

  • The method must be decorated with the “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.

[Index.razor]

@page "/"
@inject IJSRuntime JsRuntime;

<button class="btn btn-primary" @onclick="OnButtonClick">Call C# from JS</button><br /><br />

<p>@content</p>


@code {
    private static string content { get; set; }

    // Return call back from JavaScript to C#
    [JSInvokable]
    public static void JStoCSCall()
    {
        content = "C# Method called from JavaScript";
    }

    // Invoked by button clicking and calls JavaScript function.
    private async Task OnButtonClick()
    {
        await JsRuntime.InvokeAsync<object>("CStoJSCall");
    }
}

Add the C# function invoke statement to a script tag in the body of the wwwroot/index.html file.

[index.html]

<body>
      . . .
      . . .

   <script>
        function CStoJSCall() {
            // Invoke to call C# function from JavaScript.
            DotNet.invokeMethodAsync('BlazorWasmApp', 'JStoCSCall');
        }
    </script>
</body >

Refer to “Call .NET methods from JavaScript functions in ASP.NET Core Blazor” 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

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

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

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;
        }
    });
}
Permalink

To avoid memory leaks, dispose the DotNetObjectReference instance created by a component properly and allow proper garbage collection. The DotNetObjectReference instance should be disposed either at component side or JavaScript side.

Use the following patterns to dispose DotNetObjectReference at the component level.

  1. Implement IDisposable interface in the component.
  2. Add Dispose method and dispose DotNetObjectReference object inside the Dispose method.
@implements IDisposable
@inject IJSRuntime jsRuntime
 
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
 
@code { 
 
    DotNetObjectReference<HelloClass> dotNetObject { get; set; }
 
    protected override void OnInitialized()
    {
        dotNetObject = DotNetObjectReference.Create<HelloClass>(new HelloClass());
    }
 
    async Task IncrementCount()
    {
        await jsRuntime.InvokeVoidAsync("MyJavaScriptFunction", new object[] { dotNetObject });
    }
 
    void IDisposable.Dispose()
    {
        dotNetObject?.Dispose();
    }
}
 
@code{
 
    public class HelloClass
    {
        [JSInvokable]
        public void CustomMethod() { }
    }
}

When a component doesn’t dispose the DotNetObjectReference instance, it should be disposed at the JavaScript side as follows.

window.MyJavaScriptFunction = function (dotnetRef) {
    dotnetRef.dispose();
}
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

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

To get current user details in a Blazor page, we need to inject the dependency IHttpContextAccessor. We need to configure the IHttpContextAccessor service in the startup.cs as follows.

[startup.cs]

public void ConfigureServices(IServiceCollection services)
{
            services.AddHttpContextAccessor();
}
[index.razor]

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

<h1>@UserName</h1>

@code {
 public string UserName;

 protected override async Task OnInitializedAsync()
 {
        UserName = httpContextAccessor.HttpContext.User.Identity.Name
 }
}
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 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 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

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

To detect keypress event in a div tag, use the @onkeydown event on the current element. In the created example there is a div element with keydown event, and on rendering, the focus to the div element is set by using the JS Interop.

[script.js]
window.SetFocusToElement = (element) => {
         element.focus();
};
[index.razor]
@inject IJSRuntime jsRuntime
@using Microsoft.AspNetCore.Components.Web

<div class="jumbotron"  @onkeydown="@KeyDown"  tabindex="0"  @ref="myDiv">
            <h1 class="display-4"> @KeyPressed </h1>
</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);
        }
    }
    protected void KeyDown(KeyboardEventArgs args)
    {
        KeyPressed = $"Key Pressed: [{args.Key}]";// get key pressed in the arguments
    }
}
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

Error CS1061 ‘IJSRuntime’ does not contain a definition for ‘Current’ and no accessible extension method ‘Current’ accepting a first argument of type ‘IJSRuntime’ could be found (are you missing a using directive or an assembly reference?)

Solution

In ASP.NET Core 3.0.0-preview3, the Microsoft.Interop.JSRuntime.Current has been removed.

@inject IJSRuntime JsRuntime;


@code {
    protected void CallJSMethod()
    {
        JSRuntime.InvokeAsync<bool>("JSMethod");
    }
}

Reference link: https://github.com/aspnet/AspNetCore/issues/8117

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

In Blazor, IJSRuntime interface is used to invoke a JavaScript function from .NET.

Using the InvokeAsync<T> method of IJSRuntime abstraction, we can call the JavaScript function. This method takes the function name and function parameters as the argument.

Task<T> InvokeAsync<T>(string identifier, params object[] args);

The JavaScript function should always be written in the index.html file. Open the wwwroot/index.html file and put in the following code.

<html>
<head></head>
<body>
    <app>Loading...</app>

    <script src="_framework/blazor.webassembly.js"></script>
    <script>
        function JSMethod() {
            document.getElementById('demop').innerText = "Javascript Method Invoked";
        }
</body>
</html>

Open JSInterop.cshtmland put in the following code.

@page "/jsinterop"
@inject IJSRuntime JsRuntime;

<h1>JavaScript Interop</h1>

<hr />

<button class="btn btn-primary" @onclick="@CallJSMethod">Call JS Method</button>

<br />
<div id="demop"></div>

@code {
    Protected async void CallJSMethod()
    {
        await JSRuntime.InvokeAsync<string>("JSMethod");
    }
}

The method CallJSMethod will call JS function JSMethod by using the JSRuntime.InvokeAsync method.

Important notes

  • Do not write your JS code in the .cshtml file. This is not allowed in Blazor and the compiler will throw an error. Always put your JS code in the wwwroot/index.html file.
  • Always add your custom <script> tag after “<script src=”_framework/blazor.webassembly.js”> </script>” in the <body> section of the index.html file. This is to ensure that your custom script will execute after loading the “blazor.webassembly.js” script.

Reference 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

You have to refer to the JavaScript method implemented JS (external-script.js) file in index.html properly and then call the function from .NET using IJSRuntime.

[wwwroot/index.html]

<body>
    <app>Loading...</app>

    <script src="_framework/blazor.webassembly.js"></script>
    <script src="external-script.js"></script>
</body>

[wwwroot/external-script.js]

window.methods = {
    print: function (message) {
        return "from js " + message
    }
}

[Pages/Index.razor]

@inject IJSRuntime JSRuntime

@code {
  private async void PrintMessage()
  {
    Console.WriteLine(await JSRuntime.InvokeAsync<string>("methods.print", "here is the message"));
  }

}
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=/";
   }    
}
Permalink

You have to access the DOM elements in OnAfterRender or OnAfterRenderAsync of the Blazor component lifecycle.

[JS Helper]

window.methods = {    
    accessDOM: function () {
        // access DOM here
        $(".btn").text();
    }
}

[Razor]

@inject IJSRuntime JSRuntime

<button type="button" class="btn btn-primary">Submit</button>
@code{
    protected override void OnAfterRender(bool firstRender)
    {
        base.OnAfterRender(firstRender);
        JSRuntime.InvokeAsync<object>("methods.accessDOM");
    }
}

Have a look at the Blazor component lifecycle for more information.

Permalink

This is a known bug and is resolved in the upcoming release of Blazor Preview 3. [Issue Resolved]

[wwwroot/index.html]

<script>
        window.interopDuringOnInit = function () {
            return "Hello World";
        }
</script>

[Razor]

@code {
    string Greeting;

    protected override async Task OnInitializedAsync()
    {
        try
        {            
            Greeting = await JSRuntime.InvokeAsync<string>("interopDuringOnInit");
        }
        catch (Exception ex)
        {
            Console.WriteLine("Could not invoke interop during OnInit, " + ex.ToString());
        }
    }
}

Refer to the thread Tasks returned from JSRuntime.InvokeAsync during OnInitAsync never finishes for more information.

Permalink

The InvokeAsync accepts only params object[] args, so the array of objects is parsed as a single, top-level entry in args. You have to pass the array of objects as a single object by casting. The following code only passes the single array object.

[JS helper]

window.debugOut = function(content) {
 console.dir(content);
}

[Razor]

await JSRuntime.InvokeAsync<object>("debugOut", new Person[] {
     new Person{FirstName=" Nancy",LastName=” Davolio”},
      new Person{FirstName=" Andrew", LastName=” Fuller”}
});

By casting the array into an object, it retrieves all the values.

await JSRuntime.InvokeAsync< object >("debugOut", (object) new Person[] {
     new Person{FirstName=" Nancy",LastName=” Davolio”},
      new Person{FirstName=" Andrew", LastName=” Fuller”}
});

Refer to the following link for more information. https://github.com/aspnet/AspNetCore/issues/8743

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.