Creating Your First Modal Pop Up Custom Component Using Blazor Web Assembly And .NET Core 3.1

Introduction

 
In our web applications, we often need to display a pop up to add a new entity. This pop up is validated and managed using Ja avascript framework.
 
In this article we will be using Blazor Web assembly and C# to create our modal popup as Blazor component and use it in any page.
 
We will also do data validations on this pop-up using C# without the use of JavaScript.
 
Once the data is validated using API it will be saved in SQL database.
 
Prerequisites
 
This article assumes you have a basic working knowledge of Blazor web assembly and .NET Core.
 
Through this article, we will cover the following topics,
  • How to create custom modal pop up component in Blazor?
  • How to use custom component on any razor pages?
  • How to call Data service in Blazor app and save user data using Entity Framework core?
Output
 
Application with Modal popup will look like below,
 
 
Pop Up Validations
 

Implementation


Before implementation, you need to know the prerequisite.

We need to create a new Blazor web assembly project with .NET Core hosted.
 
The basic project structure is as shown below.
 
  • EmployeePortal.Client is Blazor Web assembly Project
  • EmployeePortal.Server is .NET Core 3.1 Project Where our API and Database Repository would reside
  • EmployeePoral.Shared is .NET Standard Library Project which would hold the required Models for our project  

Creating the modal component

 
Create a new component folder in our client project and add new Razor component.The detailed structure of client folder is mentioned below.
 
 
Add the below code in AddEmployeeDialog.razor
  1. @if (ShowDialog)  
  2. {  
  3.   
  4. <div class="modal fade show d-block" id="exampleModal" tabindex="-1" role="dialog">  
  5.     <div class="modal-dialog" role="document">  
  6.         <div class="modal-content">  
  7.             <div class="modal-header">  
  8.                 <h5 class="modal-title" id="titleLabel">Add Employee</h5>  
  9.                 <button type="button" class="close" @onclick="@Close" data-dismiss="modal" aria-label="Close">  
  10.                     <span aria-hidden="true">×</span>  
  11.                 </button>  
  12.             </div>  
  13.             <div class="modal-body">  
  14.                 <EditForm Model="@Employee" OnValidSubmit="@HandleValidSubmit">  
  15.                     <DataAnnotationsValidator />  
  16.                     <ValidationSummary />  
  17.                     <div class="form-group">  
  18.                         <label for="lastName">Last name: </label>  
  19.                         <InputText id="lastName" class="form-control" @bind-Value="@Employee.LastName" placeholder="Enter last name"></InputText>  
  20.                         <ValidationMessage For="@(() => Employee.LastName)" />  
  21.                     </div>  
  22.                     <div class="form-group">  
  23.                         <label for="firstName">First name: </label>  
  24.                         <InputText id="firstName" class="form-control" @bind-Value="@Employee.FirstName" placeholder="Enter first name"></InputText>  
  25.                         <ValidationMessage For="@(() => Employee.FirstName)" />  
  26.                     </div>  
  27.                     <div class="form-group">  
  28.                         <label for="email">Email: </label>  
  29.                         <InputText id="email" class="form-control" @bind-Value="@Employee.Email" placeholder="Enter email"></InputText>  
  30.                         <ValidationMessage For="@(() => Employee.Email)" />  
  31.                     </div>  
  32.                     <button type="submit" class="btn btn-primary">Save employee</button>  
  33.                     <a class="btn btn-outline-primary" @onclick="@Close">Close</a>  
  34.                 </EditForm>  
  35.             </div>  
  36.         </div>  
  37.     </div>  
  38. </div>  
  39. }  
Add the below code in AddEmployeeDialog.cs 
  • This is our component class which would invoke EmployeeDataservice
  • Which would inturn call .NET Core API using System
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Threading.Tasks;  
  5. using EmployeePortal.Shared;  
  6. using EmployeePortal.Client.Services;  
  7. using Microsoft.AspNetCore.Components;  
  8. namespace EmployeePortal.Client.Components {  
  9.     public partial class AddEmployeeDialog: ComponentBase {  
  10.         public Employee Employee {  
  11.             get;  
  12.             set;  
  13.         } = new Employee {};  
  14.         [Inject]  
  15.         public IEmployeeDataService EmployeeDataService {  
  16.             get;  
  17.             set;  
  18.         }  
  19.         public bool ShowDialog {  
  20.             get;  
  21.             set;  
  22.         }  
  23.         [Parameter]  
  24.         public EventCallback < bool > CloseEventCallback {  
  25.             get;  
  26.             set;  
  27.         }  
  28.         public void Show() {  
  29.             ResetDialog();  
  30.             ShowDialog = true;  
  31.             StateHasChanged();  
  32.         }  
  33.         public void Close() {  
  34.             ShowDialog = false;  
  35.             StateHasChanged();  
  36.         }  
  37.         private void ResetDialog() {  
  38.             Employee = new Employee {};  
  39.         }  
  40.         protected async Task HandleValidSubmit() {  
  41.             await EmployeeDataService.AddEmployee(Employee);  
  42.             ShowDialog = false;  
  43.             await CloseEventCallback.InvokeAsync(true);  
  44.             StateHasChanged();  
  45.         }  
  46.     }  
  47. }  

Validate and Save Capture Data using Data service and .NET Core API

 
Create a new Service Folder and Add new Employee Service
 
Register Data service in program.cs of client project
  1. builder.Services.AddHttpClient<IEmployeeDataService, EmployeeDataService>(client => client.BaseAddress = new Uri(builder.HostEnvironment.BaseAddress));  
Data Service would have AddEmployee function as below which would call the .NET Core API
  1. public async Task < Employee > AddEmployee(Employee employee) {  
  2.     var employeeJson = new StringContent(JsonSerializer.Serialize(employee), Encoding.UTF8, "application/json");  
  3.     var response = await _httpClient.PostAsync($ "api/employee", employeeJson);  
  4.     if (response.IsSuccessStatusCode) {  
  5.         return await JsonSerializer.DeserializeAsync < Employee > (await response.Content.ReadAsStreamAsync());  
  6.     }  
  7.     return null;  
  8. }  
In .NET Core Project create a new API contoller as below
  1. [Route("api/employee")]  
  2. [HttpPost]  
  3. public IActionResult CreateEmployee([FromBody] Employee employee) {  
  4.     if (employee == nullreturn BadRequest();  
  5.     if (employee.FirstName == string.Empty || employee.LastName == string.Empty) {  
  6.         ModelState.AddModelError("Name/FirstName""The name or first name shouldn't be empty");  
  7.     }  
  8.     if (!ModelState.IsValid) return BadRequest(ModelState);  
  9.     var createdEmployee = _employeeRepository.AddEmployee(employee);  
  10.     return Created("employee", createdEmployee);  
  11. }  
Register Repository in Startup.cs
  1. services.AddScoped<IEmployeeRepository, EmployeeRepository>();  
  2. }   
Repository to save data in database
  1. public Employee AddEmployee(Employee employee) {  
  2.     var addedEntity = _appDbContext.Employees.Add(employee);  
  3.     _appDbContext.SaveChanges();  
  4.     return addedEntity.Entity;  
  5. }  

Using our custom Created component on home page

 
Create a new razor page Employee and important component using this syntax
  1. @page"/"  
  2. @using EmployeePortal.Client.Components;  
  3. <button@onclick="QuickAddEmployee"class="btn btn-dark table-btn quick-add-btn">  +  </button>  
  4. <AddEmployeeDialog@ref="AddEmployeeDialog"></AddEmployeeDialog>  
The page class is as below.
  1. using System;  
  2. using System.ComponentModel.DataAnnotations;  
  3. using System.ComponentModel.DataAnnotations.Schema;  
  4. namespace EmployeePortal.Shared {  
  5.     [Table("Employee")]  
  6.     public partial class Employee {  
  7.         public int EmployeeId {  
  8.             get;  
  9.             set;  
  10.         }  
  11.         [Required]  
  12.         [StringLength(50, ErrorMessage = "First name is too long.")]  
  13.         public string FirstName {  
  14.             get;  
  15.             set;  
  16.         }  
  17.         [Required]  
  18.         [StringLength(50, ErrorMessage = "Last name is too long.")]  
  19.         public string LastName {  
  20.             get;  
  21.             set;  
  22.         }  
  23.         [Required]  
  24.         [EmailAddress]  
  25.         public string Email {  
  26.             get;  
  27.             set;  
  28.         }  
  29.         public string Street {  
  30.             get;  
  31.             set;  
  32.         }  
  33.         public string Zip {  
  34.             get;  
  35.             set;  
  36.         }  
  37.         public string City {  
  38.             get;  
  39.             set;  
  40.         }  
  41.         public string PhoneNumber {  
  42.             get;  
  43.             set;  
  44.         }  
  45.         [StringLength(1000, ErrorMessage = "Comment length can't exceed 1000 characters.")]  
  46.         public string Comment {  
  47.             get;  
  48.             set;  
  49.         }  
  50.     }  
  51. }  

Summary

 
Through this article we have learned how to create Custom Blazor component modal and validate user input. This also covers how to save capture data into SQL db using .NET Core API.

Thanks a lot for reading. I hope you liked this article. Please share your valuable suggestions and feedback. Write in the comment box in case you have any questions. Have a good day!