For my current job, our JavaScript framework of choice is Knockout.js. Whilst it’s not necessarily the flavour of the month for JavaScript frameworks but what I can appreciate about Knockout’s design is that it provides a solid MVVM foundation and does it very well. It’s most definitely not as “batteries included” as Angular, nor is it “pure” as libraries like React but it definitely has everything needed to produce quality web applications. Steve Sanderson’s creation always felt like a balanced one to me, and so when I found out that Microsoft’s experimental framework Blazor was created by him it piqued my interests.

Blazor is a web framework which allows developers to create single page applications using .NET. Traditional single page applications are very JavaScript heavy but with the rise of WebAssembly and asm.js Blazor allows you to write web applications for the browser using C# and Razor Views ( .cshtml files). Blazor uses an in-browser mono runtime, this means no transpilation down to JavaScript but instead interfacing directly with the browser using WebAssembly/asm.js.

Whilst Knockout is still in development, the idea of using .NET across the whole stack is pretty exciting to say the least. Whilst Knockout.js is not a Microsoft product, Steve Sanderson is a Microsoft Employee and you will find that Blazor’s design and feature set lends itself to Knockout developers who are looking to leverage newer frameworks for their projects. Let’s explore some of the major parts of Knockout.js and how Blazor provides very similar features.

The Standard Blazor Project

Knockout.js is very unopinionated in how it can be included in your project, Blazor does not share this feature. Creating a new Blazor project in Visual Studio (New Project -> ASP.NET Core -> Blazor) you will be given a standard directory structure for your applications.

I love order

If you have worked with a Razor Pages project, this shouldn’t look unfamiliar. Pages is the directory which you create your main pages for the application, routing included, whilst Shared is where you can define components that are used throughout the applications. The wwwroot folder is where you include standard web resources such as stylesheets and images. If we looked at the counter page for the standard Blazor project we can get an idea of what a standard Blazor page looks like:

As you can see, imports and page declarations are kept at the top of the page any functionality is included in the @functions section. Blazor does support having a backing C# file, as to whether this becomes the standard for developers I’m not so sure about as it is a matter of preference. Personally I’m torn, the backing .cshtml.cs file always made sense to me however having worked with Vue’s single file components the function section doesn’t feel wrong to me. I of course will get into the syntax of Blazor in this article, first lets have a look at how it handles data in the application.

Basic Databinding with Observables

The foundations of Knockout.js are Observables. Observables in Knockout.js provide a means of creating ViewModels for your components. Using ko.observable() you can create a wrapper for a value which can be subscribed to and notify other dependents when it is changed.

In Blazor, observables are thrown out the window in place of standard properties. Meaning that something like this:

this.someString = ko.observable("The string value");

Is equivalent to the following in Blazor

public string SomeString { get; set; } = "The string value";

Developers who have worked with WPF, UWP, Xamarin.Forms and most recently Uno (I wrote an article about that too) may notice that there is no need to implement any INotifyPropertyChanged methods for this observable property, this is because binding behaviour is handled by Blazor. Views in Blazor are just .cshtml files, meaning that creating a view that renders this new property is as easy as the following:

This is one way databinding, if we wanted to create a two way binding with a form input for example we would need to use a different syntax.

In Knockout.js, you achieve this with the value (or textInput ) binding, an example of it looking like:

<input type="text" data-bind="value: someStringValue"/>

In Blazor, we have a standard bind directive which creates two-way bindings automatically with a property and a form element:

Note that the textInput behaviour of updating with every keypress is not yet supported, hopefully this is implemented soon.

When working with collections, Knockout provides the ObservableArray which can be iterated over using the foreach binding.

Working with collections in Blazor is much easier, using the standard List<T> class and a foreach loop within you Razor markup.

It’s that easy, Blazor automatically re-rendering the UI when a new item is added. One other thing to note is unlike Knockout which uses click and event to handle event based input; Blazor binds C# functions to JavaScript events seamlessly. You can even define event listeners inline using onclick=@((ev) => { /** Your code **/}) .

Computed Properties

Knockout uses its dependency system to provide developers with Computed properties. Computed properties are extensions on Knockout observables which will automatically update when observables it depends on has changed. They are created using the ko.computed or (preferably) ko.pureComputed methods, and take in a function such as:

this.greeting = ko.pureComputed(() => `Hello ${this.name()}`);

Computeds are incredibly powerful as they provide a simple way of creating reactive observables which don’t need to be manually updated.

In Blazor, as with Observables, the functionality of Computeds can be recreated with vanilla C# properties. Say we wanted to create property which returned the length of SomeStrings :

This pattern is super powerful and easy to pick up, showing off Blazor’s strength of rewarding .NET Developers with a web framework that is just C#.

Components

Newer versions of Knockout support a component system. This allows developers to encapsulate logic into a single component and basically tie a View to a ViewModel. Components are the new standard in web development, frameworks like React even allowing users to create “pure components” which have no state and instead render based on data from other components. Blazor is built on components from the ground up. Each page is a component, which can include other components- .cshtml files equating to a component.

The easiest way to create a reusable component is to add a .cshtml file to the Shared directory, let’s create a Greeter for this example.

If we wanted to make a greeter for my name, it would look like:

<Greeter Name="Alex"></Greeter>

As you can see, parameters are just properties with an attribute. Blazor is already setting standards and conventions with this syntax-Visual Studio showing a warning if a parameter is public.

Why hello to you too

Component parameters, like with Knockout, can be more than static values. You are able to pass variables as a parameter using Razor syntax ( Name=”@someValue” ). That’s all that’s required, updating the someValue property updating the greeting displayed by the component.

That, is Blazor.

Blazor obviously doesn’t aim to be identical to Knockout (as the name implies Razor parity is higher up on the list) but it’s clear that it provides a lot of what Knockout and other frameworks provide. C# in the browser is a very exciting piece of technology and whilst writing this article it was hard not to think about the future of web development if Blazor were to kick off. If you are as interested as I am, there’s plenty of documentation available already and Visual Studio’s tooling for Blazor is coming along amazingly. Steve Sanderson’s newest framework shows a very promising future for the web, one that users of Knockout should definitely consider embracing in the years to come.