6/20/2022 Admin

Creating A Step-By-Step End-To-End Database MAUI Blazor Application


MAUI Blazor allows us to create applications that run natively on the operating system (rather than in a web browser). In addition to running our applications on Windows, MAUI Blazor allows us to run our applications on Android, iOS, and MacOS.

Note: MAUI Blazor allows you to create applications that run on multiple platforms, however, this tutorial only covers creating an application that runs on Windows.

A Look at The Completed Application

image

When the application is run, you will need to navigate to the Fetch data page to interact with the code described in the tutorial below.

image

Click the Add New Forecast button to add a new forecast.

image

Enter the forecast in Celsius, Fahrenheit, and a Summary and click the Save button.

The data is saved to an SQLite database.

image

The forecast will appear in the grid.

Clicking the Edit button will allow you to edit the forecast by opening it up in a Popup.

image

The Popup will allow you to make changes and click the Save button to update the record.

Optionally, you can click the Delete button to delete the record.

Clicking the X button will close the Popup without making any changes.

Prerequisites

Create The MAUI Blazor Application

image

Open Visual Studio.

image

Select Create a new Project.

image

Select .Net MAUI Blazor App and click Next.

image

Name it EndToEnd and click Next.

image

Select .Net 6.

Click Create.

image

The project will be created.

Configure the SQLite Database

image

Right-click on the Project node and select Manage NuGet Packages…

image

Add the following NuGet package: sqlite-net-pc

image

Next,  open MauiProgram.cs.

Replace:

								
builder.Services.AddSingleton<WeatherForecastService>();

With:

								
									// Set path to the SQLite database (it will be created if it does not exist)
								
var dbPath =
								
									Path.Combine(
								
									Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData),
								
									@"WeatherForecasts.db");
								

								
									// Register WeatherForecastService and the SQLite database
								
builder.Services.AddSingleton<WeatherForecastService>(
								
									s => ActivatorUtilities.CreateInstance<WeatherForecastService>(s, dbPath));

Create Weather Forecast Service

image

Open WeatherForecast.cs and replace all the code with the following code:

								
									using
									SQLite;
								

								
									namespace
									EndToEnd.Data;
								

								
									public
									class
									WeatherForecast
								
{
								
									[PrimaryKey, AutoIncrement]
								
									public
									int
									Id {
									get;
									set; }
								
									public
									DateTime Date {
									get;
									set; }
								

								
									public
									int
									TemperatureC {
									get;
									set; }
								

								
									public
									int
									TemperatureF {
									get;
									set; }
								

								
									[MaxLength(4000)]
								
									public
									string
									Summary {
									get;
									set; }
								
}

This code defines the WeatherForecast database table that will hold the data.

Code in the WeatherForecastService (CreateTableAsync) will use this definition to create the table in the SQLite database.

image

Open WeatherForecastService.cs and replace all the code with the following code:

								
									using
									SQLite;
								

								
									namespace
									EndToEnd.Data;
								

								
									public
									class
									WeatherForecastService
								
{
								
									string
									_dbPath;
								

								
									public
									string
									StatusMessage {
									get;
									set; }
								
									private
									SQLiteAsyncConnection conn;
								

								
									public
									WeatherForecastService(string
									dbPath)
								
									{
								
									_dbPath = dbPath;
								
									}
								
									private
									async Task InitAsync()
								
									{
								
									// Don't Create database if it exists
								
									if
									(conn !=
									null)
								
									return;
								

								
									// Create database and WeatherForecast Table
								
									conn =
									new
									SQLiteAsyncConnection(_dbPath);
								
									await conn.CreateTableAsync<WeatherForecast>();
								
									}
								

								
									public
									async Task<List<WeatherForecast>> GetForecastAsync()
								
									{
								
									await InitAsync();
								
									return
									await conn.Table<WeatherForecast>().ToListAsync();
								
									}
								

								
									public
									async Task<WeatherForecast> CreateForecastAsync(
								
									WeatherForecast paramWeatherForecast)
								
									{
								
									// Insert
								
									await conn.InsertAsync(paramWeatherForecast);
								

								
									// return the object with the
								
									// auto incremented Id populated
								
									return
									paramWeatherForecast;
								
									}
								

								
									public
									async Task<WeatherForecast> UpdateForecastAsync(
								
									WeatherForecast paramWeatherForecast)
								
									{
								
									// Update
								
									await conn.UpdateAsync(paramWeatherForecast);
								

								
									// Return the updated object
								
									return
									paramWeatherForecast;
								
									}
								

								
									public
									async Task<WeatherForecast> DeleteForecastAsync(
								
									WeatherForecast paramWeatherForecast)
								
									{
								
									// Delete
								
									await conn.DeleteAsync(paramWeatherForecast);
								

								
									return
									paramWeatherForecast;
								
									}
								
}

This code will create the SQLite database, if it does not already exist, and create the WeatherForecast table.

It also exposes methods that will allow code, to be added later, that will Create, Read, Update, and Delete data.

Create The User Interface

image

Open the FetchData.razor file.

Replace all the code with the following code:

								
@page "/fetchdata"
								

								
@using EndToEnd.Data
								
@inject WeatherForecastService ForecastService
								

								
									<
									h1
									>Weather forecast</
									h1
									>
								

								
									<
									p
									style="color:red"
									>@Error</
									p
									>
								

								
@if (forecasts == null)
								
{
								
									<!-- Show this if the current user has no data... yet... -->
								
									<
									p
									>
									<
									em
									>Loading...</
									em
									>
									</
									p
									>
								
}

Add the following code that will display a UI of the data in the forecasts collection if it is not null (note, it can still be empty if there is no data):

								
else
								
{
								
									<!-- Show the forecasts for the current user -->
								
									<
									table
									class="table"
									>
								
									<
									thead
									>
								
									<
									tr
									>
								
									<
									th
									>Date</
									th
									>
								
									<
									th
									>Temp. (C)</
									th
									>
								
									<
									th
									>Temp. (F)</
									th
									>
								
									<
									th
									>Summary</
									th
									>
								
									<
									th
									>
									</
									th
									>
								
									</
									tr
									>
								
									</
									thead
									>
								
									<
									tbody
									>
								
									@foreach (var forecast in forecasts)
								
									{
								
									<
									tr
									>
								
									<
									td
									>@forecast.Date.ToShortDateString()</
									td
									>
								
									<
									td
									>@forecast.TemperatureC</
									td
									>
								
									<
									td
									>@forecast.TemperatureF</
									td
									>
								
									<
									td
									>@forecast.Summary</
									td
									>
								
									<
									td
									>
								
									<!-- Edit the current forecast -->
								
									<
									button
									class="btn btn-primary"
								
									@onclick="(() => EditForecast(forecast))"
									>
								
									Edit
								
									</
									button
									>
								
									</
									td
									>
								
									</
									tr
									>
								
									}
								
									</
									tbody
									>
								
									</
									table
									>
								
									<
									p
									>
								
									<!-- Add a new forecast -->
								
									<
									button
									class="btn btn-success"
								
									@onclick="AddNewForecast"
									>
								
									Add New Forecast
								
									</
									button
									>
								
									</
									p
									>
								

Finally, add the following code that will display a popup to edit a forecast:

								
									@if (ShowPopup)
								
									{
								
									<!-- This is the popup to create or edit a forecast -->
								
									<
									div
									class="modal"
									tabindex="-1"
									style="display:block"
									role="dialog"
									>
								
									<
									div
									class="modal-dialog"
									>
								
									<
									div
									class="modal-content"
									>
								
									<
									div
									class="modal-header"
									>
								
									<
									h3
									class="modal-title"
									>Edit Forecast</
									h3
									>
								
									<!-- Button to close the popup -->
								
									<
									button
									type="button"
									class="close"
								
									@onclick="ClosePopup"
									>
								
									<
									span
									aria-hidden="true"
									>X</
									span
									>
								
									</
									button
									>
								
									</
									div
									>
								
									<!-- Edit form for the current forecast -->
								
									<
									div
									class="modal-body"
									>
								
									<
									input
									class="form-control"
									type="text"
								
									placeholder="Celsius forecast"
								
									@bind="objWeatherForecast.TemperatureC"
									/>
								
									<
									input
									class="form-control"
									type="text"
								
									placeholder="Fahrenheit forecast"
								
									@bind="objWeatherForecast.TemperatureF"
									/>
								
									<
									input
									class="form-control"
									type="text"
								
									placeholder="Summary"
								
									@bind="objWeatherForecast.Summary"
									/>
								
									<
									br
									/>
								
									<!-- Button to save the forecast -->
								
									<
									button
									class="btn btn-success"
								
									@onclick="SaveForecast"
									>
								
									Save
								
									</
									button
									>&nbsp;
								
									<!-- Only show delete button if not a new record -->
								
									@if (objWeatherForecast.Id > 0)
								
									{
								
									<!-- Button to delete the forecast -->
								
									<
									button
									class="btn btn-danger"
								
									@onclick="DeleteForecast"
									>
								
									Delete
								
									</
									button
									>
								
									}
								
									</
									div
									>
								
									</
									div
									>
								
									</
									div
									>
								
									</
									div
									>
								
									}
								

								
}

Create The Code For The User Interface

Add the following code that will create needed fields and populate the forecasts collection on page load:

								
@code
								
{
								
									string
									Error = "";
								
									List<WeatherForecast> forecasts =
									new
									List<WeatherForecast>();
								
									WeatherForecast objWeatherForecast =
									new
									WeatherForecast();
								
									bool
									ShowPopup =
									false;
								

								
									protected
									override
									async Task OnInitializedAsync()
								
									{
								
									// Get the forecasts
								
									forecasts = await ForecastService.GetForecastAsync();
								
									}

Add the following code that will open the Popup to allow a new forecast to be added, or to edit an existing forecast:

								
									void
									AddNewForecast()
								
									{
								
									// Make new forecast
								
									objWeatherForecast =
									new
									WeatherForecast();
								

								
									// Set Id to 0 so we know it is a new record
								
									objWeatherForecast.Id = 0;
								

								
									// Open the Popup
								
									ShowPopup =
									true;
								
									}
								

								
									void
									EditForecast(WeatherForecast weatherForecast)
								
									{
								
									// Set the selected forecast
								
									// as the current forecast
								
									objWeatherForecast = weatherForecast;
								

								
									// Open the Popup
								
									ShowPopup =
									true;
								
									}
								

							

Add the following code that will close the Popup if the user clicks the X (cancel) button:

								
									void
									ClosePopup()
								
									{
								
									// Close the Popup
								
									ShowPopup =
									false;
								
									}

Add the following code that will save a forecast:

								
async Task SaveForecast()
								
{
								
									// Close the Popup
								
									ShowPopup =
									false;
								
									Error = "";
								

								
									try
								
									{
								
									// A new forecast will have the Id set to 0
								
									if
									(objWeatherForecast.Id == 0)
								
									{
								
									// Create new forecast
								
									WeatherForecast objNewWeatherForecast =
									new
									WeatherForecast();
								
									objNewWeatherForecast.Date = System.DateTime.Now;
								
									objNewWeatherForecast.Summary = objWeatherForecast.Summary;
								
									objNewWeatherForecast.TemperatureC =
								
									Convert.ToInt32(objWeatherForecast.TemperatureC);
								
									objNewWeatherForecast.TemperatureF =
								
									Convert.ToInt32(objWeatherForecast.TemperatureF);
								

								
									// Save the result
								
									var NewWeatherForecast =
								
									await ForecastService.CreateForecastAsync(objNewWeatherForecast);
								

								
									// Add the Forcast
								
									forecasts.Add(NewWeatherForecast);
								
									}
								
									else
								
									{
								
									// This is an update
								
									await ForecastService.UpdateForecastAsync(objWeatherForecast);
								
									}
								
									}
								
									catch
									(Exception ex)
								
									{
								
									Error = ex.Message;
								
									}
								
}

Finally, Add the following code that will delete a forecast:

								
									async Task DeleteForecast()
								
									{
								
									// Close the Popup
								
									ShowPopup =
									false;
								

								
									try
								
									{
								
									Error = "";
								

								
									// Delete the forecast
								
									await ForecastService.DeleteForecastAsync(objWeatherForecast);
								

								
									// Remove the Forcast
								
									forecasts.Remove(objWeatherForecast);
								
									}
								
									catch
									(Exception ex)
								
									{
								
									Error = ex.Message;
								
									}
								
									}
								
									}

Links

Build a .NET MAUI Blazor app

Adding SQLite to the .NET MAUI application

Store local data with SQLite in a .NET MAUI app

.NET Multi-platform App UI documentation

New Resources to Get Started with .NET MAUI

.Net MAUI | Todo App | With Sqlite database

How do I implement authentication using SQLite in Blazor?

Blazor Help Website Links

Creating A Step-By-Step End-To-End Database Server-Side Blazor Application

Creating A Step-By-Step End-To-End Database Client-Side (WebAssembly) Blazor Application

Download

The project is available on the Downloads page on this site.

You must have Visual Studio Preview 2022 (or higher) installed to run the code.

An error has occurred. This application may no longer respond until reloaded. Reload 🗙