Blazor - it's not yet another web framework (YAWF)
This time it’s different…I promise
It is 2018 and it seems like we get a new web framework every few months and that always makes me think of this article from 2016, I know it’s a few years old but does an amazing job of setting the scene. One of my favorite tech quotes ‘No JavaScript frameworks were created during the writing of this article’ ha ha!
Anyway, onwards and upwards.
I’ve written about WebAssembly a while back but in case you don’t know what I’m talking about you can find info here.
Blazor is the .NET implementation that allows use to run C# and HTML in the browser, using good old Razor Pages template language from ASP.NET!
But this is starting to pop up more and more, most recently CloudFlare announced you can use WebAssembly on their edge worker nodes for more complex edge computing scenarios, more here.
Back of the .NET
I started out working on MS Access and using Visual Basic, I know…I’ll be 40 next year! C# and ASP.NET was next so I am no stranger to this, but the JaveScript client side revolution passed me by and I was still doing MVC, MVVM and Razor.
I’ve never been a UI person, I can definitely appreciate good design but most of my demos are for backend functional stuff, not showing reactive UI. Blazor has really opened my options up with getting into client side applications again.
For me getting started was easy, update VS to the latest, install latest .NET Core 2.1 SDK then just needed to install the language services for Blazor and then File, New Project.
There is actually a couple of nice Blazor templates, one specifically for just a client side app and also a full blown Client - Server - Shared (or Common) class library…that’s right I can have a shared library between client and server!
I’d seen a number of sample and demo apps using this template so I wanted to try and do something a little bit different and build a static site and Functions backend so I could have a fully serverless .NET application.
.NET Everywhere
The idea for this was also fueled by a presentation I was doing on Cognitive Services, I was using the Text Moderator API to detect Personally Identifiable Information (PII) in web form submissions. So I needed a web form application and figured I build this using a Blazor client app hosted statically in Azure Blob Storage and the backend running in Azure Functions.
I didn’t want to have to build the entire app from scratch so I forked the eShop code from the .NET architecture examples, that have a Razor page example which I was going to port to Blazor.
This was relatively simple, forms over data and some great two way data binding options using components, all the code is here so feel free to check it out.
I did however run into a couple of issues get the calls to the backend Function to work. I decided to put a Function in front of the Cognitive Service, to provide an abstraction and also once I have the client side done and loaded into blob it was easier to run a full integration test without have to upload the site each time.
Blazor has some built in support for JSON APIs and even some helper methods, it uses SimpleJson although the decision around this seems to be based on size of the assembly. For whatever reason and way too much time troubleshooting I could not get the built in helpers using SimpleJson working, I ended up writing my own HttpClientExtension
method with Newtonsoft.Json as a I wanted to deserilaise to a typed object.
That decision didn’t come without it’s own consequence’s, I was now getting a silent build failure (it’s an experimental framework ok!) which again I didn’t pick up for a few hours. This was reporting an error during build but not failing, along the lines of Cannot find declaration of exported type 'System.Threading.Semaphore' from the assembly
which is actually down to the aggressive settings of the Mono linker which is a tool that ship the minimal intermediate language (IL) and was getting rid of a bit too much. This is a known issue and was resolved by disabling the linker via .csproj setting <BlazorLinkOnBuild>false</BlazorLinkOnBuild>
Once I had that fixed it was relatively straight forward and really nice to have some code reuse across client and server application. It is still early days for Blazor on the client but this looks really promising, maybe the new Json APIs in .NET 3.0 will help too!