Create master detail components in Blazor Server (UI and Tables)
Some time ago I wrote a
multipart article series on developing master detail UI using ASP.NET Core
MVC. ASP.NET Core MVC is a server side framework. Modern applications often
prefer to use rich client side frameworks over traditional server side
processing. ASP.NET Core provides Blazor (Server and WebAssembly) as a framework
for building rich client side web apps. It would be interesting to see how the
master detail user interface can be built using Blazor. To that end this
multipart article series is going to show you in detail how Blazor Server can be
put to use for developing master detail pages. Although there are good third
party options such as grids that offer this functionality built into them, you
won't use any third party component in this example. You will use what's
available in Blazor and along the way you will also learn many features of
Blazor such as creating components, loading components dynamically, and creating
custom events.
Before you go to code level details it would be nice to familiarize yourself
with the sample application that you are going to build.
You will use two SQL Server tables namely Teams and TeamMembers. Teams is the
master table and contains information about a team such as TeamID, Name, and
Description. A Team can have one or more members. The members are stored in
TeamMembers table. Thus TeamMembers is a detail table and contains TeamMemberID,
Name, and Email.
Look at the following figure that shows the main page of the application.
As you can see, this is a grid showing master records. Each master record can
be viewed, modified, or deleted using the Manage Team button. Clicking on the
Manage Members button shows the detail records in another grid. The Insert
button at the top allows you to add a new master record.
The following figure shows how a master record can be modified using the
Manage Team button.
Clicking on the Insert button displays this data entry UI :
Clicking on the Manage Members shows the detail grid as follows:
You can perform CRUD operations on the detail records similar to the master
records.
Now that you have some idea about the application, let's see the structure of
Teams and TeamMembers tables. I have added these tables to the Northwind
database using Visual Studio Server Explorer but you can create a new database
if you so wish.
The Teams table is shown below:
The Teams table consists of three columns - TeamID, Name, and Description.
TeamID is an identity column and acts as the primary key of the table.
The TeamMembers table is shown next:
The TeamMembers table contains four columns - TeamMemberID, TeamID, Name, and
Email. The TeamMemberID is an identity column and acts as the primary key for
the table. TeamID column is a foreign key column that references to the TeamID
from the Teams table.
To add the foreign key constraint, open TeamMembers table definitation and
right click on the Foreign Keys node.
Click on the Add New Foreign Key menu option so that the required T-SQL
clause is added to the T-SQL pane below the table designer. Modify the T-SQL
script to resemble the following:
After adding the foreign key constraint as discussed above, close all the
open table designers exit the Server Explorer.
Now that our database tables are ready we can go ahead and create an Entity
Framework Core model to perform data access.
Begin by creating a new Blazor Server project.
Add NuGet package for Microsoft.EntityFrameworkCore.SqlServer.
Then add three class files to tje Data folder namely Team.cs, TeamMember.cs,
and AppDbContext.cs.
Open TeamMember.cs file and add entity class as shown below:
public class TeamMember
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TeamMemberID { get; set; }
public int TeamID { get; set; }
public string Name { get; set; }
public string Email { get; set; }
}
The TeamMember entity class is quite straightforward and contains the
necessary properties matching the TeamMembers table schema.
Next, open Team.cs file and add Team entity class to it as shown below:
public class Team
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TeamID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
[ForeignKey("TeamID")]
public List Members { get; set; }
}
Notice the Members navigation property that will hold the TeamMember entities
for a Team under consideration. We will load the Members property explicitly
through code as discussed in the next part of this article series.
Finally, open the AppDbContext.cs file and add the AppDbContext class as
shown below:
public class AppDbContext:DbContext
{
public DbSet Teams { get; set; }
public DbSet TeamMembers { get; set; }
public AppDbContext(DbContextOptions
options):base(options)
{
}
}
The AppDbContext class houses two DbSet properties namely Teams and
TeamMembers.
You can register the AppDbContext with the DI container in the Program.cs
file. To do so, open the Program.cs and add the following code:
...
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddRazorPages();
builder.Services.AddServerSideBlazor();
builder.Services.AddSingleton<WeatherForecastService>();
var connStr = builder.Configuration.GetConnectionString("AppDb");
builder.Services.AddDbContext<AppDbContext>(options => {
options.UseSqlServer(connStr);
});
var app = builder.Build();
...
Here, you read the database connection string stored in the appsettings.json
file and supply it to the UseSqlServer() method.
The connection string stored in the appsettings.json looks like this:
"ConnectionStrings": {
"AppDb": "data source=.;initial
catalog=Northwind;integrated security=true"
}
Make sure to change the database connection string as per your development
setup.
You will learn about the overall web application structure and begin
developing the required Blazor components in the next part of this article
series.
That's it for now! Keep coding!!