Web App Development Sans JavaScript, with Microsoft Blazor
In this tutorial, David Eastman dives into the JS-less world of Microsoft's Blazor, with a little help from a man in a shiny purple blazer.
Mar 11th, 2023 4:00am by
- Strong Visual Studio integration. After all, this is the shining star in the .NET firmament.
- Some sort of clean template method for the HTML.
- Either the ability to use Bootstrap or something with a similar modular nature for visual components.
- A relatively painless loop between editing and seeing the result. This form of hot reloading is what you spend most of your time doing with web development.
<code class="language-bash">TheNewStack> dotnet --version
7.0.200</code>
<code class="language-bash">TheNewStack> dotnet new
The 'dotnet new' command creates a .NET project based on a template.
Common templates are:
Template Name Short Name Language Tags
---
[ASP.NET](http://asp.net/) Core Web App webapp,razor [C#] Web/MVC/Razor Pages
Blazor Server App blazorserver [C#] Web/Blazor
Class Library classlib [C#],F#,VB Common/Library
Console App console [C#],F#,VB Common/Console</code>
<code class="language-bash">>dotnet new blazorserver -o FirstBlazorApp</code>
This is pleasantly HTML with some obvious adaptions. (So technically, Razor is the server-side markup language, and is the bit doing the templating — hence the suffix.)
After some certificate admin, the app runs and directs me to a simple demo front end on my localhost:7075.
If you are familiar with Rails or Sinatra, you will recognize the @page directive in Index.razor as a route to handle HTTP requests — in this case, those requesting the root of the site.
Visual Studio helps me see that SurveyPrompt and PageTitle are clearly HTML interlopers, but that’s what we need. In fact, as the man in the purple jacket points out, there is already a SurveyPrompt.razor file within the shared directory. So we have a nice component architecture (or partial in something like Rails) and it is clear the parent passes the parameter Title into the mix:
<code class="language-html"><div class="alert alert-secondary mt-4">
...
<strong>@Title</strong>
...
and tell us what you think.
</div>
@code {
// Demonstrates how a parent component can supply parameters
[Parameter]
public string? Title { get; set; }
}</code>
So one would assume it had a “/Counter” route of some sort. And it does:
<code class="language-html">@page "/counter"
<PageTitle>Counter</PageTitle>
<h1>Counter</h1>
<p role="status">Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
private int currentCount = 0;
private void IncrementCount()
{
currentCount++;
}
}</code>
<code class="language-html"><Router AppAssembly="@typeof(App).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
<FocusOnNavigate RouteData="@routeData" Selector="h1" />
</Found>
<NotFound>
<PageTitle>Not found</PageTitle>
<LayoutView Layout="@typeof(MainLayout)">
<p role="alert">Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router></code>
<code class="language-html">@inherits LayoutComponentBase
<PageTitle>FirstBlazorApp</PageTitle>
<div class="page">
<div class="sidebar">
<NavMenu />
</div>
<main>
<div class="top-row px-4">
<a href="https://docs.microsoft.com/aspnet/" target="_blank">About</a>
</div>
<article class="content px-4">
@Body
</article>
</main>
</div></code>
YOUTUBE.COM/THENEWSTACK
Tech moves fast, don't miss an episode. Subscribe to our YouTube
channel to stream all our podcasts, interviews, demos, and more.