How to Build Web Barcode Reader with Blazor WebAssembly

Blazor is a web framework developed by Microsoft. It enables developers to create web apps using C# and HTML. However, calling existing JavaScript APIs is inevitable while developing a Blazor project. This article will help web developers who want to build web barcode reader apps using Blazor WebAssembly and Dynamsoft JavaScript Barcode SDK.

Blazor Architecture

Blazor provides two templates, Blazor WebAssembly and Blazor Server.

Blazor WebAssembly

Blazor Server

Blazor server runs client-side UI logic on the server-side and sends the UI changes via Websocket. To conveniently handle JavaScript interop calls, I pick Blazor WebAssembly to implement the web barcode reader sample.

Invoking Dynamsoft JavaScript Barcode APIs in Blazor WebAssembly Project

Create a Blazor App with the Blazor WebAssembly template:

dotnet new blazorwasm -o BlazorBarcodeSample

Then add a new page to the project:

cd BlazorBarcodeSample
dotnet new razorcomponent -n BarcodeReader -o Pages

After that, add a BarcodeReader attribute to Pages/Index.razor:

@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

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

So far, we can run the app and view the homepage:

dotnet run
Blazor hello world

When running the app for the first time, we can open the developer console to observe what is going on.

blazor wasm

A dotnet.wasm file and some *.dll files are fetched and cached by the web browser.

We can make some changes to the UI by adding <button> and <p> elements.

Index.razor:

@page "/"

<h1>Blazor Barcode Sample</h1>

<BarcodeReader />

BarcodeReader.razor:

@page "/barcodereader"

<button class="btn btn-primary" >Read Barcodes from Files</button>
<p style="color:green;font-style:italic">@result</p>

@code {
    private static String result = "No Barcode Found";
    
}

Rerun the app to view the UI changes:

blazor barcode ui

If we reopen the developer console, we will find that only the BlazorBarcodeSample.dll has been fetched again.

blazor component

The next step is to empower the app with barcode scanning functionalities.

Add Dynamsoft JavaScript Barcode SDK to wwwroot/index.html, and then create a jsInterop.js file for interoperation between JavaScript and .NET:

<!DOCTYPE html>
<html>

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
    <title>BlazorBarcodeSample</title>
    <base href="/" />
    <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
    <link href="css/app.css" rel="stylesheet" />
    <script src="https://cdn.jsdelivr.net/npm/dynamsoft-javascript-barcode@7.6.0/dist/dbr.js" data-productKeys="LICENSE-KEY"></script>
</head>

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

</html>

Open jsInterop.js. Add the following code to initialize Dynamsoft Barcode Reader:

var barcodereader = null;
(async () => {
    barcodereader = await Dynamsoft.BarcodeReader.createInstance();
    await barcodereader.updateRuntimeSettings('balance');
    let settings = await barcodereader.getRuntimeSettings();
    barcodereader.updateRuntimeSettings(settings);
})();

To interact with .NET, we can use a JavaScript variable to store the reference of the .NET object:

var dotnetRef = null;
window.jsFunctions = {
    init: function(obj) {
        dotnetRef = obj;
    },
};

In order to pass .NET object reference to JavaScript, inject JavaScript runtime and override the OnInitialized() method in BarcodeReader.razor:

@inject IJSRuntime JSRuntime
@code {
    private static String result = "No Barcode Found";

    protected override void OnInitialized()
    {
        JSRuntime.InvokeVoidAsync("jsFunctions.init", DotNetObjectReference.Create(this));
    }
    
}

What we are going to do is to select an image file from the disk drive and read barcodes from the image. Therefore, add a button click event for calling the JavaScript barcode decoding method:

<button class="btn btn-primary" @onclick="ReadBarcodes">Read Barcodes from Files</button>
@code {
    private static String result = "No Barcode Found";

    protected override void OnInitialized()
    {
        JSRuntime.InvokeVoidAsync("jsFunctions.init", DotNetObjectReference.Create(this));
    }
    
    public async Task ReadBarcodes()
    {
        await JSRuntime.InvokeVoidAsync(
                "jsFunctions.selectFile");
    }
}

In the meantime, create a .NET function for receiving barcode decoding results from JavaScript:

[JSInvokable]
public void ReturnBarcodeResultsAsync(String text)
    {
        result = text;
        this.StateHasChanged();
    }

Don’t forget to use StateHasChanged() to refresh the UI.

Here is the JavaScript implementation:

window.jsFunctions = {
    init: function(obj) {
        dotnetRef = obj;
    },
    selectFile: function () {
        let input = document.createElement("input");
        input.type = "file";
        input.onchange = async function () {
            let file = input.files[0];
            try {
                await barcodereader.decode(file).then((results) => {
                    let txts = [];
                    try {
                        for (let i = 0; i < results.length; ++i) {
                            txts.push(results[i].BarcodeText);
                        }
                        let barcoderesults = txts.join(', ');
                        if (txts.length == 0) {
                            barcoderesults = 'No barcode found';
                        }
    
                        console.log(barcoderesults);
                        
                        if (dotnetRef) {
                            dotnetRef.invokeMethodAsync('ReturnBarcodeResultsAsync', barcoderesults);
                        }
                    } catch (e) {
                    }
                });
            } catch (error) {
                alert(error);
            }
            
        };
        input.click();
    },
};

Now we can test the Blazor WebAssembly app with some barcode images.

code93
blazor barcode sample

Finally, let’s remove FetchData.razor, Counter.razor, SurveyPrompt.razor, and their relevant code to refine the project.

Blazor WebAssembly barcode

Source Code

https://github.com/yushulx/blazor-barcode-sample