Blazor in .NET 5

In today’s blog post, I am going to about Blazer in .NET 5.0. This blog post is going to be the first of the series on Blazor.

The topic of Blazor in .NET 5.0, is pretty vast. So I don’t think it is going to be possible to cover every aspect of Blazer in a single blog post.

Hence, I am going to have a series and in this blog post, I am just going to do a basic
introduction to Blazer. And the following are the topics I am going to cover:

  • Introduction of Blazor
    • Blazor WebAssembly
    • Server-side Blazor
  • Code behind to separate code from HTML

What is Blazor

So let us first start with what is Blazer? Blazer is a web technology which lets us build a web-based user interface using C# as a client-side scripting language instead of
JavaScript.

In other words, Blazer is also a framework for building Single Page Applications just like Angular or React.

Traditionally we use JavaScript for building a web-based user interface. Where JavaScript is the client-side scripting language of choice and HTML and CSS as the markup language.

With Blazor, HTML and CSS remains constant, meaning when building a web-based user interface with Blazer we are still going to use HTML and
CSS as markup language and style sheet. But as a scripting language, it is going to be C#.

The advantage

The biggest advantage of Blazor in my opinion is that we can share code between server and client components. This is a feature Node developers have been taking advantage of for a long time.

If you are a C# developer who has never worked on JavaScript before, this is definitely a huge advantage. It will make it much easier for C# developers to start building a web-based client-side user interface using C#.

The extension for the Blazor file is .razor. And syntax of the files is the same as for ASP.NET Razor applications. So if you have the knowledge of ASP.NET Razor applications, it will be very easy for you to start with Blazor.

Two ways Blazor can run

Blazor can run two different ways. It can either run on browser or on the server.

WebAssembly

Blazor can run on the Browser directly using a technology called WebAssembly. With WebAssembly, .NET CLR runs on the browser, allowing C# code to execute on the client-side browser. This also allows common code and Nuget packages to share across client and server code.

Blazor Server

Blazor also runs client-side logic on the server. In this setting, the client-side user interface events and the server responses communicate with each other using SignalR. And the Blazor client-side scripts responsible for handling server-side responses also manage the DOM manipulations.

Server-based implementation has always been there, meaning you could do the same thing with any JavaScript and HTML application. This is nothing new and if you’re using SignalR you might be doing something very similar.

Maybe not as advanced as executing everything on the server-side. But similar technology of communicating real-time events between client and server.

In my opinion, running Blazer on browser using WebAssembly is groundbreaking technology.

JavaScript interop

In Blazor applications, C# code can easily call JavaScript libraries using JavaScript interop. This opens up a lot of opportunities to use the popular JavaScript libraries.

When running Blazor WebAssembly, it is straight forward as the interop happens on the browser. Whereas if you are using Server-based Blazor implementation, there is a bit of magic done by the Blazor to make it happen.

Fate of Blazor in long term

The next question is, which I am pretty sure would be in a lot of people’s minds is that is Blazer going to be another fail experiment like Silverlight?

If you know about Silverlight you know what I am talking about. If you don’t know about SilverLight, then let me give you a quick introduction.

SilverLight was another client-side technology which was introduced by
Microsoft in late 2007. SilverLight was a technology in which you can write code in C# or VB.NET to run on a browser. And you can use XAML syntax for creating a user interface.

The good news is that WebAssembly is fundamentally different and in my opinion, it is here to stay. WebAssembly (Wasm) is an open standard for running binaries in the browser. The WebAssembly is memory safe and runs inside of a sandbox.

As of writing this blog, the most popular modern browsers support WebAssembly. Which includes Chrome, Firefox, Edge, and Safari, both on desktop as well as mobile devices. So this is something which is definitely here to stay.

And server-side Blazer component as I mentioned earlier which uses SignalR. Which also supported by all modern browsers. So both client WebAssembly and Server-based Blazor are going to have support in the foreseeable future. So in my opinion I think Blazer is going to stay and it is not going to see the fate of Silverlight.

New ASP.NET Core Blazor WebAssembly Application

Now let us start creating a new Blazor WebAssembly application.

Firstly, to do that, I will open up Visual Studio 2019. Once Visual Studio opens up, I will select the menu File -> New -> Project. This will open the Create a new Project project popup window.

Secondly, in the Create a new Project popup window, I will select Blazor App from the project template and click on the Next button.

Thirdly, on the next page, I will provide the name of the application as Blazor.Demo and click on the Create button.

Finally, on the final page, I will select the Blazor WebAssembly App template option. And I will keep other values default (.NET 5.0) and click on the Create button.

new blazor app

Deep-dive into Program.cs

Once the project is ready, let us explore what are the files created out of the box. So the first one is the same as any other application will be. The Program.cs, and it has the Main method.

using Microsoft.AspNetCore.Components.WebAssembly.Hosting;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Net.Http;
using System.Threading.Tasks;

namespace Blazor.Demo
{
    public static class Program
    {
        public static async Task Main(string[] args)
        {
            var builder = WebAssemblyHostBuilder.CreateDefault(args);
            builder.RootComponents.Add<App>("#app");

            builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });

            await builder.Build().RunAsync();
        }
    }
}

In the Main method, the first thing we are going to do is call the static method CreateDefault on WebAssemblyHostBuilder type. This is going to create an instance of WebAssemblyHostBuilder.

The Root component

In the next line, we are calling the Add method on the RootComponents property (RootComponentMappingCollection) of the WebAssemblyHostBuilder instance.

And for the generic type, we are passing the App type of the project. And here the App type acts as the root component of the Blazor WebAssembly.

This is very similar to how Angular has the root App component. And here as a parameter to the Add method, we are passing #app as a selector which is the Id of the top-level DIV element in the body of the index.html.

Services property of WebAssemblyHostBuilder

In the next line the Main method we are using the IServiceCollection through the Services property of the WebAssemblyHostBuilder instance to add HttpClient to the dependency injection container.

The base address is the address for the HttpClient is of the same server which is hosting the Blazor WebAssembly.

App.razor

Now, let us get to the App.razor file. The App class of the App.razor is the main component of the Blazor application. This is the entry point to the application.

Now if we look inside the App.razor, it starts with the Router. And the Router is an ASP.NET Core routing component that routes to each component with a specific route.

The router attaches the currently executing assembly as the AppAssembly. The @page directive in the .razor file defines the route of the particular component.

The router has two tags here one is Found and the other is NotFound. NotFound will be executed when a route is not registered. Otherwise, the Found will be executed.

If a route is registered through @page directive, the RouteView renders the specific component with the route.

The optional DefaultLayout property contains the default layout that the application should use. In this case, the default layout is MainLayout.

MainLayout

The MainLayout.razor file contains the top-level layout for this application. The MainLayout.razor file has a @Body directive. This is where individual components will load.

The MainLayout.razor has a side bard for navigation and a common text on top. And finally, it contains the @Body directive, where all the components will load. And the components are loaded based on the route path.

So if you think about it, this part is just like any other Single Page Application (SPA) framework like Angular. It always starts with an entire application with the router configured and then it has the main layout. And inside of the main layout, it will have things like navigation, and the individual components will load based on the route.

Components

All the components are available inside the Pages folder.

The common components are available inside the Shared folder.

Every component can have its own CCS files. For example NavMenu.razor has its own CSS file with the name NavMenu.razor.css. Visual Studio groups the file properly for easy management.

But everything is bundled into a single assembly during the build process and it goes to the client-side browser.

Root component

For the Index.razer page the @page directive is set to "/". Which means when the page is loaded without any routes, by default Index.razor component will be loaded.

The Index.razor contains an h1 tag with just hello world, a welcome message. And after that, it calls a component called SurveyPrompt.

The ServeyPrompt component contains some texts and then it has a public property Title. And the Title property was set from the Index.razor. This also shows how to write a shared component which can expect parameter from outside.

Code Behind file

If we look inside the Counter.razor file created. The C# code for this file co-exists with the HTML tags.

@page "/counter"

<h1>Counter</h1>

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

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

@code {
    private int currentCount = 0;

    private void IncrementCount()
    {
        currentCount++;
    }
}

The page starts with a @page directive that defines the route of the component. After that all HTML tags. And finally, a @code directive, which contains all the C# code.

If you look into any of the SPA frameworks like Angular, you will see JavaScript files are usually separate from the HTML file. And that makes things much tidier and better manageable in long run.

So, we want the same separation of code in Blazor. Good news is that we can do the same with Blazor application.

Counter.razor.cs

Firstly, to achieve this, I will create a new file Counter.razor.cs. And I will make the class a partial class since the compiler already creates a dynamic partial class for Counter.

Secondly, I will copy all the code inside of the @code directive and paste it inside of the newly created Counter partial class.

using System;

namespace Blazor.Demo.Pages
{
    partial class Counter
    {
        private int currentCount = 0;

        private void IncrementCount()
        {
            currentCount++;
            Console.WriteLine($"Count: {currentCount}");
        }
    }
}

Finally, I will remove the @code directive from the Counter.razor.

@page "/counter"

<h1>Counter</h1>

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

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

Now one thing you will notice in the remaining HTML code, we still have a couple of directives.

Firstly, we are using @counterCount, which is a C# variable. Secondly, we are using the @onclick directive to attach the client event of the button to C# IncrementCount function.

If you have worked on any other SPA framework like Angular, this syntax will look very similar. This is how the View Model properties and event handlers are accessed. The only difference here is that the variable and function is going to be in C#.

Tough these are C# classes, but this will be downloaded on the client-side and will be executed in the browser.

Now, if I run the application, the behavior will still remain the same as before this change.

Conclusion

So far Blazor looks really promising. It has the potential of becoming the Single Page Application Framework of choice for C# developers. I am going to explore more to see this is something I will want to use in Production settings.

I have documented this blog on my YouTube, If you want to follow along, here is the video.