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.
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.