Introduction

Lately, I've been focusing on writing about JavaScript, and it's been a while since I wrote a .NET based article. The reason for this is that a lot is going on in the JavaScript world, and I pretty much enjoy writing it and exploring new things around it.

On the other hand, things are shifting in Microsoft as well, and from day one, I was intrigued by Blazor, and I feel like it's the right time to cover this topic here.

The State of SPA Development

What is a SPA? SPA is a shorthand, and it stands for a Single Page Application. This means that, even though you see the "page" and URL changing, you never actually leave the current page. The server is never called again to re-render the HTML. Everything is handled on the client. Today, in order to start developing these applications, you need a lot of decisions to make. Let's cover the 3 most important ones, but there are more things to care about than the ones listed below.

decision

First, you must decide whether you are going to write the application in the latest JavaScript (ECMAScript) or TypeScript. There are other picks out there, but these two languages are the main ones used today. Luckily, either pick has a strong community behind it and a lot of tooling provided for us out of the box.

This leads to the second decision which is to decide which framework are you going to use. A vast number of small and not so small frameworks exist in JavaScript ecosystem, but usually, you will pick between Vue, React, Angular and let's say Ember. In logic and provided core functionality, they are not that many different things. With each of them, you can use components, mixins, module import/export, and all that modern web development requires these days.

And last but not least, you need to pick the appropriate tolling and configuration for your project. Depending on the language and the framework, you will start defining your toolchain. Some of the tools, like webpack, are applicable for all situations listed above, and yet some tools arent. For example, if you've chosen TypeScript as the core language, you must be sure that the tools you are going to pick also have typings created.

On the other hand, if you've chosen ECMAScript, you need to use Babel to compile it down to support most browsers. If IE is one of the target browsers as well, additional polyfills are required...and so on.

Since this is not the focus of the article, I will stop here with pointing out that, If this part is done poorly, it can shake your application foundation later on.

What is WebAssembly?

For years, we had only one programming language to use natively in web browsers, and that's JavaScript. For a brief moment, there was Flash and ActionScript, but both of them were squashed by the one mentioned above. Let's face it, JavaScript is overwhelmingly adopted and loved, by millions of developers.

With WebAssembly, there is a new possibility, and a new era is upon us, I believe. But what is WebAssembly, or by shorthand WASM?

wasm

It's a binary format designed to ensure near-native performance for web applications and a compilation target for any high-level programming language. With support by major browsers, it's becoming a serious competitor to JavaScript.

If you like JavaScript, you will wonder why do we need this? But, you need to understand that many people don't like it and will embrace this with both hands because with WebAssembly they can write the whole application using Java, or C# thus being able to share the logic between the server and the client. With WASM we don't need the knowledge of at least two programming languages to write a web app, only one will suffice, and it can be server-side language because it will be compiled down and represented in a format understandable to browsers. Whether this will be a JavaScript replacement or addition, only time will tell.

What is Blazor?

Overview

Blazor is a SPA (Single-Page-Application) framework created by Microsoft. It's component based and enables developers to build a rich client-side UI with .NET running in the background. This means that we can write C# instead of JavaScript and get the same result. If you've read the previous section, you can conclude that this is possible thanks to the WebAssembly. For many people, this is a big "Yay" or "Finally", considering that not everyone loves JavaScript. They are simply forced to use it because of the monopoly it has.

If we go back to the decision section, we can say that, with Blazor, it becomes more simple. We need to make just one decision, and that is whether we are going to use Blazor or not. Everything else is provided by the .NET ecosystem. We don't need to think about the different frameworks and the corresponding tools responsible for gluing everything together.

With Blazor, we get the following benefits:

  • C# instead of JavaScript
  • Sharing logic between client and server
  • .NET tooling ecosystem
  • .NET built-in performance and security
  • Same programming language on client and server (it's hard to follow everything in both worlds, front and backend, meaning you don't need a full-stack developer to work on a web app)

Also, we can pick between the two hosting models:

  • Client-Side
  • Server-Side

To read more about hosting models, check out this page.

The Syntax

Note that for the Blazor to run you need to have the latest .NET Core version installed. You can follow the guide here. I've successfully made it work with the Visual Studio Code and the client-side hosting model

As mentioned earlier, Blazor is a component-based framework, meaning that whenever we need to create a UI segment of the application, we would create a component. An example would be an entire page, a modal dialog, a button if so desired...etc.

Each Blazor component is usually written in Razor markdown with .razor extension and they are refered as Razor components. Inside, you can combine HTML and C# when you see fit thus making you more productive. Similar to Razor pages but the difference is that the Razor components should be used for client-side logic and composition only. Let's see how this looks like in practice.

Imagine that we want to create a message box for our application. To do it, we could create MsgBox.razor file with the following content:

<div>
  <h2>Hi from Blazor</h2>
  <p>
    Share this article if you liked it!
  </p>
</div>

After creating it, we would use it in another razor component like this:

<MsgBox />

This is all nice and neat, but we cannot do much with a static message box like this. What if we want to make it more dynamic? Is this possible with Blazor? You are right, it is :) Remember that we've mentioned that inside razor components we can mix HTML and C#? So let's do it, and make the title and the message, dynamic.

First, at the end of our HTML, we need to add @code section. Inside this section, we can write the C# code.

In order to make our title and message dynamic, we need to create, within the @code section, a C# property for each of them and decorate it with the Parameter attribute. This will tell Blazor that the values for these properties are going to be provided within the HTML, at the place where the component will be used. The actual value can be static or can be provided by the parent via data binding, for example, but this is a topic for another post.

Next, we need to update the component template to actually use these parameters. The updated MsgBox.razor component looks like this:

<div>
  <h2>@Title</h2>
  <p>
    @Message
  </p>
</div>

@code {
  [Parameter]
  private string Title { get; set; }
  [Parameter]
  private string Message { get; set; }
}

Now, we are able to pass in the desired title and message to our component thus making it more useful.

<MsgBox Title="Hi from Blazor" Message="Share this article if you liked it!" />

Another thing what dialog has are buttons. Let's say we want to add Yes and No buttons to our message box. To make things more interesting, let's add these buttons as child content. Blazors lets us, by using the ChildContent property, to render the HTML passed within the opening and closing tags of our component where we see fit, as long as is within the component template. In practice, our updated component looks like this:

<div>
  <h2>@Title</h2>
  <p>
    @Message
  </p>
  <div>
    @ChildContent
  </div>
</div>

@code {
  [Parameter]
  private string Title { get; set; }
  [Parameter]
  private string Message { get; set; }
  [Parameter]
  private RenderFragment ChildContent { get; set; }
}

What we did here is added a new Parameter property of type RenderFragment named ChildContent.

Do note that, at the time of writing this, the property name must be ChildContent, otherwise we would get an error

After doing this, usage is slightly different:

<MsgBox Title="Hi from Blazor" Message="Share this article if you liked it!">
  <button>Yes</button>
  <button>No</button>
</MsgBox>

The HTML located between the opening and closing tag of our component will replace the @ChildContent placeholder.

Our component is very much alive and dynamic at this point. We can pass in different title, message and inner content per each component instance. That's super cool! But, our buttons don't do anything. How can we attach an event handler to it? Of course, this can be done with Blazor. Let's see it in practice and update our component.

First, we need to create a method representing the event handler within the @code section, like this:


@code {
  private void OnYesClick()
  {
     // This line will actually write to the browser console, eq: console.log('Click on: YES')
     Console.WriteLine("Click on: YES"); 
  }
}

Next, we attach it to the Yes button by using the @ prefix:

  // the @ from the @onclick can be omitted and the event would still be attached
  <button @onclick="@OnYesClick">Yes</button>

NOTE: Considering that the buttons are added as a ChildContent and they are defined within the parent component, this is where we need to define our events, as well. In other words, the OnYesClick event must be defined in the parent component, in our example. If the buttons were placed within the MsgBox.razor component, instead of them being provided via ChildContent property, the events would be placed inside the @code section of it.

The parent component, where we use our MsgBox.razor could look something like this:

<h1>Hello, world!</h1>

Welcome to your new app.

<MsgBox Title="Hi from Blazor" Message="Share this article if you liked it!">
  <button @onclick="@OnYesClick">Yes</button>
  <button>No</button>
</MsgBox>

@code {
  private void OnYesClick()
  {
     // This line will actually write to the browser console, eq: console.log('Click on: YES')
     Console.WriteLine("Click on: YES"); 
  }
}

Ok, I will wrap it up with the event handlers and how they can be used in our application, but don't be mistaken, with Blazor you can do a lot more and hopefully, I will cover more parts of this framework in one of my next articles.

Conculsion

A lot of great things are upon us with Blazor and WebAssembly. I love JavaScript, don't get me wrong, but something like this will make life a lot easier for many .NET developers out there.

If you liked this post, subscribe here or follow me on twitter to stay tuned. Feel free to express your thoughts in the comment section below. And, show some love by buying me a coffee. It will keep me awake late at night while writing articles for you.

Thank you for reading and see you in the next article!