Project Introduction

I recently decided to refurbish two bathrooms and in both cases I wanted the rooms to have fully tiled walls.  Unfortunately both bathrooms have sloping ceilings, meaning that some walls were odd shapes.  I needed a way to calculate the area of each wall, in square metres, and thought this would be a good subject to test my programming skills, (or lack of them).

YouTube Video

Project Outline

I plan to have two basic pages for the application, one page to allow the user to add projects, the other will be the 'Index' page. On the Index page I envisage a drop-down list of projects, and then, responding to the selected project, a cascading series of grids for Rooms, Walls and Deductions.

A room will be able to have any number of walls associated with it (of varying shapes - which I will come to in due course). By selecting a room from the room-grid, its walls will be displayed in the wall-grid. The area of a wall will be calculated by calculating its gross area (for a simple wall, its length x height), and then deducting the area of any items that are not going to be tiled, for example doors and windows. I am calling these 'Deductions'. By selecting a room from the room-grid any associated deductions will be shown in the deductions-grid.

There are a number of complications that will need to be tackled.

  • In general terms, if a record is selected at a higher level in the hierarchy the data in the immediately lower level needs to be refreshed - but any data shown in levels further down the hierarchy must be cleared from the grids.  For example, if a project is selected, if that project has already had rooms added, those rooms need to be displayed, but as no room can be selected automatically so no data must be shown in the wall or deductions grids.
  • The wall grid will show the 'Net Area' for that wall, i.e. the area of the wall minus any deductions.  This means that as deductions are added, edited or deleted, the specific wall will need to be updated and the wall grid refreshed.
  • Deleting a record in the higher levels of the hierarchy will require a cascade delete of any records associated with it in the lower levels.

Decisions

At this stage I have decided to create a Blazor server application (but will leave the door open to conversion to Blazor WebAssembly later - possibly).

For simplicity I will not use any user authorisation, (at this stage, although it might be added later).

I have also decided to use a SQLite database.  (Thinking ahead, if I decide to publish to Azure web apps it will mean I won't need to incur any costs associated with Microsoft SQL server - the other obvious alternative.)

Because I'm familiar with these tools I also plan to use:

  • Microsoft Visual Studio 2022
  • Dapper
  • Syncfusion controls

Getting Started

With those decisions made, let's make a start.

  • Open Visual Studio and create a new Blazor Server project, using .NET 7 with no authorisation.  I've called the project/solution BlazorWallAreaCalculator.

Using the Nuget Package Manager install:

  • Dapper
  • System.Data.Sqlite.Core
  • Syncfusion:
    • Syncfusion.Licensing
    • Syncfusion.Blazor.Core
    • Syncfusion.Blazor.Themes
    • Syncfusion.Blazor.Popups
    • Syncfusion.Blazor.Inputs
    • Syncfusion.Blazor.DropDowns
    • Syncfusion.Blazor.Grid
    • Syncfusion.Blazor.Notifications

Install Syncfusion

We have installed the Syncfusion NuGet packages, but there are a number of other steps that need to be completed. These are documented here, but briefly they are:

  • Register Syncfusion Blazor Service
  • Add Style Sheet
  • Add Script Reference
  • Syncfusion Licence Key

Register Syncfusion Blazor Service

Open _Imports.razor and add the following to import the Syncfusion.Blazor namespace

@using Syncfusion.Blazor
               

Open Program.cs and add 'using Syncfusion.Blazor;' in the 'using' section, and 'builder.Services.AddSyncfusionBlazor();' in the 'builder' section as shown below:

using BlazorWallAreaCalculator.Data;
               using Microsoft.AspNetCore.Components;
               using Microsoft.AspNetCore.Components.Web;
               using Syncfusion.Blazor;
               
               var builder = WebApplication.CreateBuilder(args);
               
               // Add services to the container.
               builder.Services.AddRazorPages();
               builder.Services.AddServerSideBlazor();
               builder.Services.AddSingleton<WeatherForecastService>();
               builder.Services.AddSyncfusionBlazor();
               
               var app = builder.Build();
               ....

Add Style Sheet

Open /Pages/_Host.cshtml and add this line in the <head> section:

<head>
                   ...
                   <link href="_content/Syncfusion.Blazor.Themes/bootstrap5.css" rel="stylesheet" />
               </head>

Add Script Reference

With /Pages/_Host.cshtml still open add this line beneath the the Style Sheet line in the <head> section.

<head>
                   ...
                   <link href="_content/Syncfusion.Blazor.Themes/bootstrap5.css" rel="stylesheet" />
                   <script  src="_content/Syncfusion.Blazor.Core/scripts/syncfusion-blazor.min.js" type="text/javascript"></script>
               </head>

Licence Syncfusion

Syncfusion needs to be licensed. To obtain a licence:

  • Open the Syncfusion web page - https://www.syncfusion.com
  • Create an account if you don't already have one, and sign into your account.
  • Select 'My Dashboard' by clicking on your user name in the page header.
  • Select 'License & Downloads', followed by 'Downloads & Keys'.
  • Select 'Get License Key' and follow the instructions.

Because we are using .NET 7 we need to place the following code in Program.cs, replacing 'Your License Code' with your actual licence key.

Place the code after 'var app = builder.Build'

//Register Syncfusion license 
               Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense("Your Licence Key");
               

Move Syncfusion Licence Key to appsettings.json

Because it is possible that I will want to show, or share, code in program.cs I do not want to have the Syncfusion Licence Key explicitly shown in program.cs. To get around this problem I have moved the actual licence key to appsettings.json, and will also add appsettings.json to gitignore so that the key is not exposed on GitHub.

Summary of Tasks
  • Amend appsettings.json to add Syncfusion Licence Key
  • Modify Program.cs to read licence from appsettings.json
Change to appsettings.json

Simply add the following line to appsettings.json

"SyncfusionLicenceKey": "Your Actual Syncfusion Licence Key",
Changes to program.cs

Modify program.cs to replace the existing Syncfusion licensing code with this:

//Register Syncfusion license
               var SyncfusionLicenceKey = builder.Configuration["SyncfusionLicenceKey"];
               Syncfusion.Licensing.SyncfusionLicenseProvider.RegisterLicense(SyncfusionLicenceKey);
               

We can now safely add appsettings.json to gitignore in the knowledge that our Syncfusion Licence key is not going to get exposed.

References

Visual Studio 2022 Community Edition:

Syncfusion Community Licence:

DB Browser for SQLite: