.NET Framework .NET C# VB.NET LINQ ASP.NET Web API REST SignalR Windows Forms WPF WCF RabbitMQ PHP SQL Server MySQL PostgreSQL MariaDB SQLite MongoDB ADO.NET ORM Entity Framework Dapper XML JSON HTML5 CSS3 Bootstrap JavaScript jQuery Angular React TypeScript NPM Blazor UI/UX Responsive Web Design Redis Elasticsearch GraphQL Grafana Agile Scrum Kanban Windows Server IIS PowerShell Active Directory TFS Azure Automation Software Reverse Engineering Performance Optimization Git Jira/Confluence CI/CD TeamCity SOLID KISS DRY YAGNI
Always will be ready notify the world about expectations as easy as possible: job change page

B is for Blazor Full-Stack Web Dev

Created: Aug 25, 2020
Source: source
Views: 435

In my 2019 A-Z series, I covered Blazor for ASP.NET Core while it was still experimental. As of ASP.NET Core 3.1, server-side Blazor has now been released, while client-side Blazor (currently in preview) is expected to arrive in May 2020. This post will cover server-side Blazor, as seen in NetLearner.

To see the code in action, open the solution in Visual Studio 2019 and run the NetLearner.Blazor project. All modern web browsers should be able to run the project.


NetLearner.Blazor web app in action

Entry Point and Configuration

Let’s start with Program.cs, the entry point of the application. Just like any ASP.NET Core web application, there is a Main method that sets up the entry point. A quick call to CreateHostBuilder() in the same file ensures that two things will happen: The Generic Host will call its own CreateDefaultBuilder() method (similar to how it works in a typical ASP.NET Core web application) and it will also call UseStartup() to identify the Startup class where the application is configured.

public class Program
    public static void Main(string[] args)

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        .ConfigureWebHostDefaults(webBuilder =>

Note that the Startup class doesn’t have to be called Startup, but you do have to tell your application what it’s called. In the Startup.cs file, you will see the familiar ConfigureServices() and Configure() methods, but you won’t need any of the regular MVC-related lines of code that set up the HTTP pipeline for an MVC (or Razor Pages) application. Instead, you just need a call to AddServerSideBlazor() in ConfigureServices() and a call to MapBlazorHub() in Configure() while setting up endpoints with UseEndPoints().

public class Startup
    public void ConfigureServices(IServiceCollection services)

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        app.UseEndpoints(endpoints =>

Note that the Configure() method takes in an app object of type IApplicationBuilder, similar to the IApplicationBuilder we see in regular ASP.NET Core web apps. A call to MapFallBackToPage() indicates the “/_Host” root page, which is defined in the _Host.cshtml page in the Pages subfolder.

Rendering the Application

This “app” (formerly defined in a static “index.html” in pre-release versions) is now defined in the aforementioned “_Host.cshtml” page. This page contains an <app> element containing the main App component.

        <component type="typeof(App)" render-mode="ServerPrerendered" />

The HTML in this page has two things worth noting: an <app> element within the <body>, and a <component> element of type “App” with a render-mode attribute set to “ServerPrerendered”. This is one of 3 render modes for a Blazor component: Static, Server and ServerPrerendered. For more information on render modes, check out the official docs at:

According to the documentation, this setting “renders the component into static HTML and includes a marker for a Blazor Server app. When the user-agent starts, this marker is used to bootstrap a Blazor app.

The App component is defined in App.razor, at the root of the Blazor web app project. This App component contains nested authentication-enabled components, that make use of the MainLayout to display the single-page web application in a browser. If the user-requested routedata is found, the requested page (or root page) is displayed. If the user-requested routedata is invalid (not found), it displays a “sorry” message to the end user.

    <Router AppAssembly="@typeof(Program).Assembly">
        <Found Context="routeData">
            <AuthorizeRouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
            <LayoutView Layout="@typeof(MainLayout)">
                <p>Sorry, there's nothing at this address.</p>

The MainLayout.razor component (under /Shared) contains the following:

  • NavMenu: displays navigation menu in sidebar.
  • LoginDisplay: displays links to register and log in/out.
  • _CookieConsentPartial: displays GDPR-inspired cookie message.
  • @Body keyword: replaced by content of layout when rendered.

The _Layout.cshtml layout file (under /Pages/Shared) acts as a template and includes a call to @RenderBody to display its content. This content is determined by route info that is requested by the user, e.g. Index.razor when the root “/” is requested, LearningResources.razor when the route “/learningresources” is requested.

<div class="container">
    <main role="main" class="pb-3">

The NavMenu.razor component contains NavLinks that point to various routes. For more information about routing in Blazor, check out the official docs at:

LifeCycle Methods

A Blazor application goes through several lifecycle methods, including both asynchronous and non-asynchronous versions where applicable. Some important ones are listed below:

  • OnInitializedAsync() and OnInitialized(): invoked after receiving initial params.
  • OnParametersSetAsync() and OnParametersSet(): called after receiving params from its parent, after initialization.
  • OnAfterRenderAsync() and OnAfterRender(): called after each render.
  • ShouldRender(): used to suppress subsequent rendering of the component.
  • StateHasChanged(): called to indicate that state has changed, can be triggered manually.

These methods can be overridden and defined in the @code section (formerly @functions section) of a .razor page, e.g. LearningResources.razor.

@code {
    protected override async Task OnInitializedAsync()

Updating the UI

The C# code in LearningResources.razor includes methods to initialize the page, handle user interaction, and keep track of data changes. Every call to an event handler from an HTML element (e.g. OnClick event for an input button) can be bound to a C# method to handle that event. The StateHasChanged() method can be called manually to rerender the component, e.g. when an item is added/edited/deleted in the UI.

    <input type="button" class="btn btn-primary" value="All Resources" @onclick="(() => DataChanged())" />

private async void DataChanged()
    learningResources = await learningResourceService.Get();
    ResourceLists = await resourceListService.Get();

Note that the DataChanged() method includes some asynchronous calls to Get() methods from a service class. These are the service classes in the shared library that are also used by the MVC and Razor Pages web apps in NetLearner.

Parameters defined in the C# code can be used similar to HTML attributes when using the component, including RenderFragments can be used like nested HTML elements. These can be defined in sub-components such as ConfirmDialog.razor and ResourceDetail.razor that are inside the LearningResources.razor component.

<ResourceDetail LearningResourceObject="learningResourceObject"

Inside the subcomponent, you would define the parameters as such:

@code {
    public LearningResource LearningResourceObject { get; set; }

    public List<ResourceList> ResourceListValues { get; set; }

    public Action DataChanged { get; set; }

    public RenderFragment CustomHeader { get; set; }

For more information on the creation and use of Razor components in Blazor, check out the official documentation at:

Next Steps

Run the Blazor web app from the NetLearner repo and try using the UI to add, edit and delete items. Make sure you remove the restrictions mentioned in a previous post about NetLearner, which will allow you to register as a new user, log in and perform CRUD operations.

NetLearner.Blazor: Learning Resources

There is so much more to learn about this exciting new framework. Blazor’s reusable components can take various forms. In addition to server-side Blazor (released in late 2019 with .NET Core 3.1), you can also host Blazor apps on the client-side from within an ASP.NET Core web app. Client-side Blazor is currently in preview and is expected in a May 2020 release.



Oct 24, 2022
Author: Anton Shyrokykh
Entity Framework Core is recommended and the most popular tool for interacting with relational databases on ASP NET Core. It is powerful enough to cover most possible scenarios, but like any other tool, it has its limitations. Long time people...
Feb 25, 2023
Author: Mike Brind
Back in 2008, I wrote a series of articles about using iTextSharp to generate PDF files in an ASP.NET application. I still use iTextSharp in a large MVC 5 application that I'm in the process of migrating to ASP.NET Core....
Jun 26, 2021
SignalR is a popular software library that allows you send server code to client-side applications, like a React application. This tutorial will show you how to install SignalR on both your ASP.NET Core and React Typescript application.Creating your ApplicationsWhen creating...
Jun 25, 2022
Author: Philipp Bauknecht
Sometimes your web app needs to do work in the background periodically e.g. to sync data. This article provides a walkthrough how to implement such a background task and how to enabled/disable a background task during runtime using a RESTful...
Send message
Your name

© 1999–2023 WebDynamics
1980–... Sergey Drozdov
Area of interests: .NET | .NET Core | C# | ASP.NET | Windows Forms | WPF | Windows Phone | HTML5 | CSS3 | jQuery | AJAX | MS SQL Server | Transact-SQL | ADO.NET | Entity Framework | IIS | OOP | OOA | OOD | WCF | WPF | MSMQ | MVC | MVP | MVVM | Design Patterns | Enterprise Architecture | Scrum | Kanban
GitHub profile