Experimenting with Blazor

- Developer and Blogger
Published: Sun Mar 24 2019

This post is a quick write-up of a POC I worked on this weekend using .Net Blazor.

Blazor

What is Blazor?

Blazor is a .Net based web framework that allows us to run C# in the browser. Please note, Blazor is highly experimental at this point and should not be used for production applications.

Running C# in the browser may seem crazy, but it’s made possible by web assembly (wasm). At build time the compiler will compile regular C# code to wasm that can be executed directly by all modern browsers. This is pretty cool since it enables us to write client side applications in .Net. In my opinion the biggest benefit of this is being able to use a fantastic language like C# for client side web. This is especially helpful for devs who are already using C# for server side code.

Code

My demo is pretty simple. I basically decided to just continue my tradition of testing out new frameworks by creating treeviews. The starting point for my demo is the default project template for Visual Studio Blazor projects. I recommend checking out the official Blazor example here first. This will make it a lot easier to get started since the default template provides a sample that works out of the box.

Let’s take a look at the code.

My treeview displays a simple hierarchical view of media files, so the first thing I built was an object model to represent a directory. The code can be found below:

Directory.ts
using System; using System.Collections.Generic; using System.Text; namespace Blazor_Samples.Shared {     public class Directory     {         public bool expanded = false;         public string[] files;         public Directory[] directories;         public string name;         public Directory(string name, Directory[] directories, string[] files)         {             this.name = name;             this.directories = directories;             this.files = files;         }         public void toggle()         {             expanded = !expanded;         }         public string getIcon()         {             if (expanded)             {                 return "-";             }             return "+";         }     } }

In addition to a few node properties like name and child nodes there is also functionality to expand nodes and render the appropriate icon. I should point out that this is a pure C# class without anything specific to Blazor or even web based technology.

Next I’ll show you the landing page for my treeview in the application. I have added an index.cshtml file below.

Index.cshtml
@page "/" @using Blazor_Samples.Shared <h1>Treeview</h1> <Treeview Directories="directories"></Treeview> @functions {     Directory[] directories;     protected override void OnInit()     {         var fall2014 = new Directory("Fall 2014", new Directory[] { }, new string[] { "image1.jpg", "image2.jpg", "image3.jpg" });         var summer2014 = new Directory("Summer 2014", new Directory[] { }, new string[] { "image10.jpg", "image20.jpg", "image30.jpg" });         var pictures = new Directory("Pictures", new Directory[] { fall2014, summer2014 }, new string[] { });         var music = new Directory("Music", new Directory[] { }, new string[] { "song1.mp3", "song2.mp3" });         directories = new Directory[] { pictures, music };     } }

In index.cshtml we even get client side routing from specifying @Page "/". If you have multiple views, just define a different @Page with another unique url.

I wire up the data model inside the OnInit life cycle hook before binding the model to my Treeview component.

Let’s take a look at the Treeview component in Treeview.cshtml below.

Treeview.cshtml
@using Blazor_Samples.Shared     <ul>         @foreach (var dir in Directories)         {         <li>             <span onclick="@dir.toggle">@dir.getIcon()</span>             <span>@dir.name</span>             @if (dir.expanded)             {             <div>                 <ul>                     @foreach (var file in dir.files)                     {                         <li>@file</li>                     }                 </ul>                 <Treeview directories="dir.directories"></Treeview>             </div>             }         </li>         }     </ul> @functions {     [Parameter] Directory[] Directories { get; set; } }

The component is responsible for stamping out markup based on values in the recursive Directory data model. Notice the Treeview self reference in the template. This is what enables recursive rendering of the recursive model.

Demo

I have deployed a version of the treeview to Azure. You can check it out here.

Conclusion

At this point Blazor is considered a highly experimental project by Microsoft, but I think this already shows promise. The idea of writing client side browser applications in C# is incredibly cool! Being able to author web applications in a powerful typed language like C# can be a major improvement over adding types to Javascript via Typescript. Another huge benefit is much more seamless integration of frontend and backend code.

However, there are a few challenges with the current Blazor implementation. Running the .Net framework in the browser forces us to download a bunch of .Net dlls in the browser. As a result the application payload is huge! My simple treeview application weighs in at 5MB, which is a non starter, even on a fast connection.

I haven’t tried this yet, but there is a server based variant of Blazor that avoids .dll downloads by executing incremental view changes on the server instead. The idea is that the client sends requests to the server over as socket connection whenever a view needs to be updated. An obvious downside to this though is a lot of request back and forth between server and client. There is an article here with more details.