Creating a Blazor WebAssembly Application — Part 1

Henrique Siebert Domareski
13 min readOct 21, 2022

Blazor is an open-source framework from Microsoft that allows you to build modern front-end applications using C#, HTML, CSS and Razor. In this article, I present an introduction to Blazor, explaining the difference between the hosting options (Client-side, Server-side and Hybrid), explaining the structure of a Blazor project and demonstrating how to start creating a Blazor WebAssembly App, which provides a SPA user experience.

Introduction to Blazor

Blazor is part of ASP.NET, and allows you to build interactive Web UIs using C# code instead of JavaScript. A Blazor app is composed of reusable Web UI components implemented with C#, HTML, and CSS.

Blazor provides many benefits such as:

  • Allow you to build modern and rich interactive Web UIs using C# code instead of JavaScript.
  • Can share server-side and client-side app logic written in .NET, making it possible to reuse code logic from other .NET projects you have.
  • Have all the benefits from .NET, such as good performance, reliability and security.
  • Renders the UI as HTML and CSS for wide browser support, including mobile browsers.
  • Integrate with modern hosting platforms, such as Docker.
  • Can make use of existent .NET libraries.
  • And if you choose to use Blazor WebAssembly — which is the focus of this article — , it supports ahead-of-time (AOT) compilation, where you can compile your .NET code directly into WebAssembly (at the expense of a larger app size).

Blazor vs ASP.NET MVC with Razor

Blazor and the classic ASP.NET MVC with Razor don't work in the same way. In a Blazor application (more specifically a Blazor WebAssembly app), the app runs direct in the client browser. This is how it works: the browser makes an initial request to the server to download the application to the client, and it will run from the client browser, and API calls are used for additional data.

A classic ASP.NET MVC with Razor, works with server-side technologies (request/response model), where the request is sent to the server, the HTML is then rendered in the server and returned to the client.

Blazor Hosting Models

There are three different ways for hosting a Blazor application (the code is identical, except for a few startup files). It’s possible to have a Blazor app that runs on a server (server side), or runs directly on a client (WebAssembly / client side), or a Hybrid option. As you can imagine, each hosting options have pros and cons, you should analyze which option best fits better your needs. Here is an explanation of these hosting options and the benefits and limitations of each:

Blazor WebAssembly — Client-side

This approach provides a SPA (Single Page Application) user experience. The application runs directly in the client browser as a WebAssembly app (on a WebAssembly-based .NET runtime). The app code and the .NET runtime to host the app are downloaded to the client browser, so instead of having an app running on the server, the app is compiled and the compiled code is then downloaded to the client and executed there. The application can also be built as a PWA (Progressive Web App) which also makes it possible to use the app offline.

Blazor WebAssembly — source: Microsoft Docs

“WebAssembly (abbreviated Wasm) is a binary instruction format for a stack-based virtual machine. Wasm is designed as a portable compilation target for programming languages, enabling deployment on the web for client and server applications.” (https://webassembly.org/)

Benefits of Client-side Blazor

  • Supports ahead-of-time (AOT) compilation, where you can compile your .NET code directly into WebAssembly, which results in runtime performance improvements (at the expense of a larger app size).
  • Since the app is downloaded to the client, then there is no .NET server-side dependency. The app remains functional even if the server goes offline.
  • Provides a SPA user experience.
  • Client resources and capabilities are fully leveraged.
  • Work is offloaded from the server to the client.
  • An ASP.NET Core web server isn’t required to host the app. Serverless deployment scenarios are possible, such as serving the app from a Content Delivery Network (CDN).

Disadvantages of Client-side Blazor

  • Older browsers might not support it.
  • The app is restricted to the capabilities of the browser.
  • Capable client hardware and software (for example, WebAssembly support) are required.
  • The download size is larger, and apps take longer to load the first time the user opens the app.
  • Limited debug experience (it’s possible to debug, but there are some limitations).

Blazor Server — Server-side

With this approach, the app is executed fully on the server within an ASP.NET Core app, so the Blazor app runs on the server and sends the UI code to the browser. Keep in mind that for each user that is running the app, an instance of the app is running on the server. Between the client browser and the server-side app, a SignalR connection (using WebSockets protocol) is created to handle UI updates, event handling, and JavaScript calls.

Blazor Server — source: Microsoft Docs

[Extra]: SignalR is an open-source library that simplifies adding real-time web functionality to apps. Real-time web functionality enables server-side code to push content to clients instantly. With SignalR, every time the user performs some action in the browser, the data about the event will be sent over SignalR to the Blazor app which is running on the server, and the result will e sent back to the client and the changes are going to be applied to the DOM.

Benefits of Blazor Server

  • The download size is significantly smaller than a Blazor WebAssembly app, and the app loads much faster.
  • Full support for debugging, since .NET is used to run the app on the server.
  • Works with browsers that don’t support WebAssembly and on resource-constrained devices.
  • The app’s .NET/C# code base, including the app’s component code, isn’t served to clients.

Disadvantages of Blazor Server

  • There is no offline support, so the application needs to be connected to the server in order to run.
  • Higher latency/Network delay, since every user interaction involves a connection to the server, and this can cause delays.
  • Scaling apps with many users requires server resources to handle multiple client connections and client state.
  • An ASP.NET Core server is required to serve the app. Serverless deployment scenarios aren’t possible, such as serving the app from a Content Delivery Network (CDN).

Blazor Hybrid

Hybrid apps use a mix of native and web technologies. You can use Blazor in a native client app, where Razor components run directly in the native app (not on WebAssembly), and the Web UI based on HTML and CSS is rendered using a Web View control.

Razor components run natively in the .NET process and render web UI to an embedded Web View control using a local interop channel. WebAssembly isn’t used in Hybrid apps. (Microsoft Docs)

Hybrid Server — source: Microsoft Docs

Benefits of the Hybrid model

  • It’s possible to reuse components that can be shared across mobile, desktop, and web.
  • Web development skills, experience, and resources can be used.
  • The apps have full access to the native capabilities of the device, making it possible to interact with the device sensors, access disks, etc.

Disadvantages of the Hybrid model

  • Separate native client apps must be built, deployed, and maintained for each target platform.
  • Native client apps usually take longer to find, download, and install than accessing a web app in a browser.

Creating a Blazor WebAssembly App

Before we dive into the Blazor App, let me give some background information about the project we are going to create in this series. In previous articles, I demonstrated how to create an application using .NET Web API and Angular, and for that, I created the “BookStore” project, which you check the part 1 of this series by clicking here. So now we are going to create a similar front-end project but with Blazor WebAssembly. And this app will make use of the existent back-end service (Web API).

So let’s start creating the Blazor WASM application. You can create a new Visual Studio solution for the Blazor project, or you can create the Blazor project within the same solution you have for the .NET back-end service. I must say that I faced some issues related to hot reload when using the Blazor project and the back-end project in the same solution, when both projects run simultaneously (API and front-end), but feel free to create as you prefer. If you create the Blazor App inside the same solution of the back-end services, you can configure the solution to when starting the project, the API project and the Blazor WebAssembly project start together, to do that, right-click in the solution and go to properties > Common Properties > Startup Project > and in the “Action” dropdown select “Start” for your API project and the Blazor project.

To create a Blazor app with Visual Studio, select the option to create a new project and select “Blazor WebAssembly App”:

Inform the project name and click next:

For this project, I’m using .NET 6.0:

Then let’s run the application and you should see this page:

Hot Reload

.NET Hot Reload is supported for all ASP.NET Core 6.0+ projects, and it allows you to make changes in the code (including changes to stylesheets) while the app is running, without needing to restart the app and without losing app state.

Blazor WebAssembly supports Hot Reload with some limitations. Hot Reload reacts to most of the changes in method bodies (such as adding, removing, and editing variables, expressions, and statements), reacts to changes in the bodies of lambda expressions and local functions, and also supports adding new lambdas or local functions.

Until the date of this article (October 2022), hot reload does not support adding a new await operator, does not support yield keyword expression, does not support changing the names of method parameters and does not support changes outside of method bodies.

In Visual Studio, you can see the Hot Reload icon next to the button to run the application:

Tip: Enabling the “Hot Reload on File Save” it’s a good thing to do, as the name implies, every time you change in the app something that is supported by Hot Reload, it will automatically update the app in your browser.

Blazor Project Structure (WebAssembly)

The Blazor template provides a working application for us. This is the initial structure of a Blazor WASM app:

  • Properties/launchSettings.json — which holds the development environment configuration.
  • wwwroot folder: this is the Web Root folder for the app, which contains the app’s public static assets that will be downloaded to the client, such as images, CSS files, as well as appsettings files. The index.html file, which is the root page of the app implemented as an HTML page.
  • Pages folder: which contains the routable components/pages (the .razor files), which make up the Blazor app. When a new Blazor WASP project is created, you can find the Index.razor file (and other files) in this folder, which implements the Home page.
  • Shared folder: which contains the shared components and stylesheets such as MainLayout.razor, MainLayout.razor.css, NavMenu.razor, NavMenu.razor.css, etc.
  • _Imports.razor file: which includes common Razor directives to include in the app’s component, such as common @using directives and namespaces (global usings). Once you add them in this file, you don’t need to refer to them again in your components.
  • App.razor file: which is the app’s root component that sets up client-side routing using the Router component.
  • Program.cs file: which is the app’s entry point that sets up the WebAssembly host. In this file is where you can also add the configuration for the Depency Injection for your classes.

Blazor Components

Blazor apps are based on components, similar to other SPAs. A component in Blazor is an element of UI, such as a page, a dialog, a button, a data entry form, etc. A component is made by C# code and HTML, and contains the UI and the logic of this UI, and can be reused in your application.

A component is usually written in the form of a Razor markup page with a .razor extension in the file name (formal name is Razor component, but are also known as Blazor component) — all files in a Blazor project that have the .razor extension are components.

Just a brief explanation in case you are not familiar with Razoror never worked with it in the past, Razor allows you to switch between HTML markup and C# in the same file with IntelliSense programming support in Visual Studio, and is also used in the classic ASP.NET MVC projects. But unlike Razor Pages and MVC, which are built around a request/response model, Blazor components are used specifically for client-side UI logic and composition.

This is the default page that is created when we create the Blazor project:

Now if you check in the “Pages” folder, we already have two components: Counter.razor and FetchData.razor (the name of the component, is the file name):

The Counter component is a component on which you have a button that will sum the value 1 on each click and displays it in the UI:

Note that the HTML and the code are in the same file (in the .razor file), however, you can split it into two different files, one for the HTML, and one for the logic by using partial class. For now, to keep it simple, let’s keep both in the same file.

On line 1 we have the @page directive, which specifies a routable component with a route template and can be reached directly by a user's request in the browser at a specific URL. For this component, when the user accesses the URL "app-url/counter" it will be redirected to the Counter component page.

From line 3 up to line 9 there is the component HTML. On line 9 we have the @onclick event handler, which calls the method “IncrementCount” that is in the @code section.

From line 11 up to the end, notice the directive @code, inside this block, there are the methods and properties for the component. In this example, there is one property named CurrentCount on line 12, which value is displayed in the UI, by using the razor syntax @ in the property name (see line 7 — @currentCount). And on line 14 there is the method IncrementCount, which sum 1 value to the property.

This is the UI:

It’s also possible to use the component inside of some other page. For example, if you want to add the Counter component to the home page, you only need to add a tag to your HTML page, using the name of your component (the file name of the component), and Visual Studio also helps you with Intellisense. In this example, I added two times the Counter component as you can see in lines 11 and 12:

And now you have the two Counter components working on your Home page, and every time you click the button, it will sum 1:

Each component works in an isolated way, so in the first component I clicked the button once, and the in the second component I clicked twice, and as you can see in the image above, they are totally independent of each other.

It’s also possible to inform parameters to your component, for example, if you want to make it possible to define the numbers to be incremented on each click, you can create a new property in your component and use the [Parameter] attribute above the property (see lines 14 and 15):

And in the HTML you can inform a value to the parameter we created in the component (see line 11):

Now on each click, the counter will sum 10:

Conclusion

Blazor is a great way to create modern front-end applications using C# code instead of JavaScript, and as part of ASP.NET, brings the benefits of .NET. With Blazor you can choose the hosting model that fits better for your needs (Client side, Server side or Hybrid), and if you are already a .NET developer, you can use your C# knowledge to develop front-end applications.

In the next part of this series, we are going to create the components for Categories and Books and implement the communication with the back-end service.

This is the link for the project in GitHub:

https://github.com/henriquesd/BlazorSPABookStore

If you like this project, I kindly ask you to give a ⭐️ in the repository.

Thanks for reading!

--

--