Introduction
Confirmation modals are like pop-up messages that make using websites easier. In this article, we'll show you how to make these pop-ups in Blazor Server. We'll use special tools called parameters and EventCallback to make your code simpler, make it easier for users to interact with your site, and help your Blazor Server apps work better.
In Blazor, components are like the superheroes of web development, working together to create awesome websites. But for them to be a dream team, they need to talk to each other. That's where EventCallback and Parameter come in. In this article, we're going to learn how to create a reusable modal popup with the superpowers of these two concepts and see how they help components chat and work together smoothly in the world of Blazor.
What is a Parameter?
Parameters are values that are passed from a parent component to a child component. They allow you to communicate data downward in the component hierarchy. Parameters are unidirectional, meaning data flows from the parent to child components.
What is EventCallback?
Event callbacks are used to handle events in a child component and notify the parent component about the occurrence of an event. Event callbacks are unidirectional as well, but they allow the child component to send messages or notify the parent component about some user interaction or state change.
Create a reusable confirmation modal pop-up
Follow these steps to create a reusable modal pop-up.
Step 1. Create a Blazor Server project.
First, we need to create a Blazor Server project then you'll have a default page named index.razor. If you wish to customize this default page, you can do so by adjusting the route. For instance, you can change the route by adding @page "/your-custom-route" at the top of your desired page, allowing you to create your unique default page.
Step 2. Create a Model class named UserDetailsModel.cs.
Create a class named UserDetailsModel.cs and write this code.
namespace BlazorDemo.Data
{
public class UserDetailsModel
{
public Int64 UserId { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public int Age { get; set; }
}
}
Step 3. Add an interface class.
Then add an interface named IUserDetails.cs and write this code to call a method to catch the data from the database.
using BlazorDemo.Data;
namespace BlazorDemo.Interfaces
{
public interface IUserDetails
{
public Task<List<UserDetailsModel>>GetUserList();
}
}
Step 4. Add a class under the DAL folder.
Create a class named UserDetails.cs under the DAL folder and write this code to catch the data from the database.
using BlazorDemo.Interfaces;
using Dapper;
using System.Data;
namespace BlazorDemo.Data
{
public class UserDetails : IUserDetails
{
private readonly DapperContext _context;
private readonly ILogRepo _logRepo;
public UserDetails(DapperContext dapperContext)
{
_context = dapperContext;
_logRepo = new LogRepo(dapperContext);
}
public async Task<List<UserDetailsModel>> GetUserList()
{
List<UserDetailsModel> llst = new List<UserDetailsModel>();
try
{
using (var connection = _context.CreateConnection())
{
var procedure = "[Project_GetUsersDetails]";
llst = (await connection.QueryAsync<UserDetailsModel>(procedure, commandType: CommandType.StoredProcedure)).ToList();
}
}
catch (Exception ex)
{
}
return llst;
}
}
}
Code Explanation
using BlazorDemo.Interfaces;
Import statement for the IUserDetails interface, indicating that this class implements methods defined in that interface.
using Dapper;
Import statement for the Dapper micro-ORM, a lightweight and efficient object mapper used for database operations.
using System.Data
Import statement for the System.Data namespace, which provides ADO.NET types for working with data.
public class UserDetails : IUserDetails
Declaration of the UserDetails class, implementing the IUserDetails interface.
_context
A private field of type DapperContext represents the Dapper database context. It's injected through the constructor.
_logRepo
A private field of type ILogRepo, representing a repository for logging. It's initialized with an instance of LogRepo in the constructor.
public UserDetails(DapperContext dapperContext)
Constructor that takes a DapperContext as a parameter, injecting the Dapper context into the class.
public async Task<List<UserDetailsModel>> GetUserList()
Implementation of the GetUserList method from the IUserDetails interface. This method retrieves a list of UserDetailsModel objects from the database.
using (var connection = _context.CreateConnection())
Creates a database connection using the _context Dapper context.
var procedure = "[Project_GetUsersDetails]";
Defines a stored procedure named "Project_GetUsersDetails" to be executed.
llst = (await connection.QueryAsync<UserDetailsModel>(procedure, commandType: CommandType.StoredProcedure)).ToList();
Executes the stored procedure asynchronously and maps the results to a list of UserDetailsModel objects.
catch (Exception ex) { /* Error handling */ }
Catches and handles exceptions that may occur during the database operation. In this case, the error is not handled beyond catching the exception.
return llst;
Returns the list of UserDetailsModel objects obtained from the database.
Step 5. Add a razor component and it's code-behind class.
Now, create a Razor component named UserInfo.razor and its corresponding code-behind class named UserInfoBase.cs. In these files, we will implement a grid to show the data from the database. write this code in the UserInfo.razor page.
@page "/"
@inherits UserInfoBase;
@using BlazorDemo.Data
<RadzenGrid Data="@userDetails" TItem="UserDetailsModel" AllowPaging="true">
<Columns>
<RadzenGridColumn TItem="UserDetailsModel" Property="UserId" Title="User ID" Width="50px" />
<RadzenGridColumn TItem="UserDetailsModel" Property="FirstName" Title="First Name" Width="100px" />
<RadzenGridColumn TItem="UserDetailsModel" Property="LastName" Title="Last Name" Width="100px" />
<RadzenGridColumn TItem="UserDetailsModel" Property="Email" Title="Email" Width="100px" />
<RadzenGridColumn TItem="UserDetailsModel" Property="Age" Title="Age" Width="50px" />
</Columns>
</RadzenGrid>
}}
Code Explanation
@page "/"
Specifies that this page is the default page for the application and can be accessed at the root URL.
@inherits UserInfoBase
Instructs the page to inherit from the UserInfoBase class, which typically contains the page's logic and event handling.
@using BlazorDemo.Data
Imports the BlazorDemo.Data namespace allows the usage of types defined in this namespace within the page.
<RadzenGrid>
Blazor component that represents a data grid. It is bound to a collection of UserDetailsModel objects (userDetails). The AllowPaging="true" attribute enables pagination.
<Columns>
Defines the columns to be displayed in the grid.
<RadzenGridColumn>
Represents a column in the grid. Each column is bound to a property of the UserDetailsModel class and has specific configurations like title, width, and other display settings.
write this code in the it's code behind page UserInfoBase.cs.
using BlazorDemo.Data;
using BlazorDemo.Interfaces;
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace BlazorDemo.Pages
{
public class UserInfoBase:ComponentBase
{
public List<UserDetailsModel> userDetails = new List<UserDetailsModel>();
protected bool loading = false;
[Inject] IUserDetails iuserDetails { get; set; }
protected override async void OnInitialized()
{
await GetStaffDoc();
StateHasChanged();
}
public async Task GetStaffDoc()
{
loading = true;
try
{
userDetails = await iuserDetails.GetUserList();
}
catch (JSDisconnectedException ex)
{
// Ignore
}
catch (Exception ex)
{
}
finally
{
StateHasChanged();
loading = false;
}
}
}
}



Join the conversation! Your thoughts help the community grow.