Introduction
In my
previous blog we talked about Blazor, default Blazor project templates available with .NET Core, and how to create Blazor applications using those templates in Visual Studio 2019. At the end of the blog I also mentioned that Blazor uses ASP.NET Core Razor Components for creating the UI which increases the code reuse as we can use the same components for both Blazor.Server & Blazor WASM based applications.
The code given by the current default Blazor Templates includes the components code inside them. In this blog we will learn to create a Blazor application which has the UI components separate so that we can reuse those in both WebAssembly & Blazor server.
Step 1
Open Visual Studio 2019 to see following start screen and then click on "Create New Project" as highlighted in screenshot.
Step 2
On the Create a new project window, enter or type Razor Class in the search box. It will show Razor Class Library project on top, click on that and then click Next as shown in below screenshot.
Step 3
Next we will get below screen, mention the name of project, its path and click on Create as highlighted.
Step 4
Next we will get the following screen where we have to un-check Support Pages and Views as highlighted and click on Create button.
Step 5
The default created project will have the following structure.
Step 6
Rename Component1.razor (highlighted in previous screenshot) to App.Razor and replace its code with the following code,
- <Router AppAssembly="@typeof(App).Assembly">
- <Found Context="routeData">
- <RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
- </Found>
- <NotFound>
- <LayoutView Layout="@typeof(MainLayout)">
- <p>Sorry, there's nothing at this address.</p>
- </LayoutView>
- </NotFound>
- </Router>
Step 7
Replace the default code of _Imports.razor with the following code,
- @using System.Net.Http
- @using Microsoft.AspNetCore.Authorization
- @using Microsoft.AspNetCore.Components.Forms
- @using Microsoft.AspNetCore.Components.Routing
- @using Microsoft.AspNetCore.Components.Web
- @using Microsoft.JSInterop
- @using BlazorComponents
- @using BlazorComponents.Shared
- @using BlazorComponents.Pages
Step 8
Add two Folders named Pages & Shared. The project will have the following structure now,
Step 9
Right click on Shared folder click on Add => New Item on the context menu as highlighted in the below screenshot.
Step 10
Next the following screen will appear to select the new Item type. Select Razor Component, name it and click on Add as highlighted.
Step 11
Replace the default code of MainLayout.razor with the following code,
- @inherits LayoutComponentBase
-
- <div class="sidebar">
- <NavMenu />
- </div>
-
- <div class="main">
- <div class="top-row px-4">
- <a href="https://docs.microsoft.com/en-us/aspnet/" target="_blank">About</a>
- </div>
-
- <div class="content px-4">
- @Body
- </div>
- </div>
Step 12
Repeat Steps 9 & 10 to create NavMenu.razor.
Step 13
Replace the default code of NavMenu.razor with the following code,
- <div class="top-row pl-4 navbar navbar-dark">
- <a class="navbar-brand" href="">BalzeServer</a>
- <button class="navbar-toggler" @onclick="ToggleNavMenu">
- <span class="navbar-toggler-icon"></span>
- </button>
- </div>
-
- <div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
- <ul class="nav flex-column">
- <li class="nav-item px-3">
- <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
- <span class="oi oi-home" aria-hidden="true"></span> Home
- </NavLink>
- </li>
- <li class="nav-item px-3">
- <NavLink class="nav-link" href="counter">
- <span class="oi oi-plus" aria-hidden="true"></span> Counter
- </NavLink>
- </li>
- <li class="nav-item px-3">
- <NavLink class="nav-link" href="fetchdata">
- <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch data
- </NavLink>
- </li>
- </ul>
- </div>
-
- @code {
- private bool collapseNavMenu = true;
-
- private string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
-
- private void ToggleNavMenu()
- {
- collapseNavMenu = !collapseNavMenu;
- }
- }
Step 14
Repeat Steps 9 & 10 again on Pages Folder and create Index.razor.
Step 15
Replace the default code of Index.razor with the following code,
- @page "/"
- <h1>Hello, world!</h1>
- Welcome to your new app.
Step 16
Repeat Steps 9 & 10 again on Pages Folder and create Counter.razor.
Step 17
Replace the default code of Counter.razor with the following code,
- @page "/counter"
- <h1>Counter</h1>
- <p>Current count: @currentCount</p>
- <button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
-
- @code {
- private int currentCount = 0;
-
- private void IncrementCount()
- {
- currentCount++;
- }
- }
Now our component library is ready, Basically we have recreated the default Template code in a Razor Component Library code. Now follow next Steps to use this component library in Blazor application heads.
Blazor.Server
Step 1
Right click on the Solution and Select Add=>New Project from the Context Menu as highlighted below,
Step 2
Follow the Steps 2 to 5 of
this blog to create a new Blazor.Server application, name the project as BlazorServer.
Step 3
Delete Pages & Shared Folders.
Step 4
Also Delete _Import.Razor & App.Razor From the BlazorServer project root. Now the project structure will look something like the following.
Step 5
Right click on BlazorServer project and select Add => Reference.. from context menu as shown below,
Step 6
Add the reference of BlazorComponents project as shown below.
Step 7
As mentioned in Step 9 above right click on BlazorServer project and select Add => New Item from context menu.
Step 8
From the New Item Dialog box select Razor Page and name it as _Host.cshtml as shown below.
Step 9
Replace the code of _Host.cshtml with the below code,
- @page "/"
- @namespace BlazorComponents
- @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
-
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="utf-8" />
- <meta name="viewport" content="width=device-width, initial-scale=1.0" />
- <title>BlazorServer</title>
- <base href="~/" />
- <link rel="stylesheet" href="css/bootstrap/bootstrap.min.css" />
- <link href="css/site.css" rel="stylesheet" />
- </head>
- <body>
- <app>
- @(await Html.RenderComponentAsync<App>(RenderMode.ServerPrerendered))
- </app>
-
- <script src="_framework/blazor.server.js"></script>
- </body>
- </html>
Step 10
Open StartUp.cs and update it's ConfigureServices method with following code. In this code we are adding MVC support to the Blazor application and setting the default path for Razor Pages (this first two lines of the method).
- public void ConfigureServices(IServiceCollection services)
- {
- services.AddMvc()
- .AddRazorPagesOptions(options => { options.RootDirectory = "/"; });
- services.AddRazorPages();
- services.AddServerSideBlazor();
- services.AddSingleton<WeatherForecastService>();
- }
Step 11
Your Blazor Server application with external component support is ready now. Execute the application now, you will get the following output which is exactly the same as the output from default Blazor Template.
In this blog we learned about how we can create a external component library with code thesame as the Blazor Default template and use that external component library in Blazor Server application. This application architecture is now future ready as we can use the same UI code for other project like Blazor WebAssembly but thats for another blog.
We will be extending this Code to use with Blazor WebAssembly in future blogs, the code of this project template is available
here at Github.