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
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.
Click the
Add New Forecast
button to add a new
forecast
.
Enter the
forecast
in
Celsius
,
Fahrenheit
, and a
Summary
and click the
Save
button.
The data is saved to an
SQLite
database.
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
.
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
Open
Visual Studio
.
Select
Create a new Project
.
Select
.Net MAUI Blazor App
and click
Next
.
Name it
EndToEnd
and click
Next
.
Select
.Net 6
.
Click
Create
.
The
project
will be created.
Configure the SQLite Database
Right-click
on the
Project
node and select
Manage NuGet Packages…
Add the following
NuGet package
:
sqlite-net-pc
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
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.
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
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):
<!-- Show the forecasts for the current user -->
<table class="table">
<thead>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
<th></th>
</thead>
<tbody>
@foreach (var forecast in forecasts)
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
<!-- Edit the current forecast -->
<button class="btn btn-primary"
@onclick="(() => EditForecast(forecast))">
</button>
</tbody>
</table>
<!-- Add a new forecast -->
<button class="btn btn-success"
@onclick="AddNewForecast">
Add New Forecast
</button>
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">
</button>
<!-- 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 = "";
// 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);
// 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;
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.