受欢迎的博客标签

ASP.NET Core Blazor (Server Side )-Integrating WebAPI Controllers with curd(wjl)

Published

 

Introduction

How to call Api controller action from server side blazor Net Core?

In this article, we will create a Single Page Application (SPA) using the server-side Blazor concepts with the help of Entity Framework Core database first approach. Single-Page Applications are web applications that load a single HTML page and dynamically update that page as the user interacts with the app.

We will be creating a sample Employee Record Management System and perform CRUD operations on it. A modal popup will display the form to handle the user inputs and the form also has a dropdown list, which will bind to a database table. We will also provide a filter option to the user to filter the employee records based on employee name.

We will be using Visual Studio 2019 and SQL Server 2017 for our demo.

Let us look at the final application.
 
 


 
 

 

step 1.Create Server Side Blazor Application

Open Visual Studio and select File >> New >> Project.

 
This will create our server-side Blazor solution. You can observe the folder structure in solution explorer, as shown in the below image,
 
 
 
 

Step 2.Creating Directory  for the Application

 
 

step 3. Creating the WEB API Controllers

\src\Presentation\WeiXinAdmin\Controllers\UserController.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;



namespace WeiXinAdmin.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class UserController : Controller
    {
        // GET: api/<controller>
        [HttpGet]
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/<controller>/5
        [HttpGet("{id}")]
        public string Get(int id)
        {
            return "value";
        }

        // POST api/<controller>
        [HttpPost]
        public void Post([FromBody]string value)
        {
        }

        // PUT api/<controller>/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/<controller>/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}
 
 

step 4. Creating the View Component

\src\Presentation\WeiXinAdmin\Pages\User\List.razor
@page "/Pages/User/List"

<h3>List</h3>

@code {

}
 

step 5.Configure web api Controllers access for the Application

You must add “MapControllers” end point in “Configure” method inside the Startup class to get service calls from Web API controller.
\src\Presentation\WeiXinAdmin\Startup.cs
   public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
            }

            app.UseStaticFiles();

            app.UseRouting();

            // ******
            // BLAZOR COOKIE Auth Code (begin)
          
            app.UseStaticFiles();
            app.UseCookiePolicy();
            app.UseAuthentication();
            app.UseAuthorization();
            // BLAZOR COOKIE Auth Code (end)
            // ******

            app.UseEndpoints(endpoints =>
            {
                endpoints.MapControllers();//add here
                endpoints.MapBlazorHub();
                endpoints.MapFallbackToPage("/_Host");
            });
        }
 
 

 Access web api the Application

step 6.create a custom HttpClient class for the Application

currently HttpClient class doesn’t contain “GetJsonAsync”, “PostJsonAsync”, and “PutJsonAsyc” methods.

We can create a custom HttpClient class to add these missing methods to handle json data.

\src\Presentation\WeiXinAdmin\Data\CustomHttpClient.cs

using Newtonsoft.Json;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;


namespace WeiXinAdmin.Data
{
    public class CustomHttpClient : HttpClient
    {
        public async Task<T> GetJsonAsync<T>(string requestUri)
        {
            HttpClient httpClient = new HttpClient();
            var httpContent = await httpClient.GetAsync(requestUri);
            string jsonContent = httpContent.Content.ReadAsStringAsync().Result;
            T obj = JsonConvert.DeserializeObject<T>(jsonContent);
            httpContent.Dispose();
            httpClient.Dispose();
            return obj;
        }
        public async Task<HttpResponseMessage> PostJsonAsync<T>(string requestUri, T content)
        {
            HttpClient httpClient = new HttpClient();
            string myContent = JsonConvert.SerializeObject(content);
            StringContent stringContent = new StringContent(myContent, Encoding.UTF8, "application/json");
            var response = await httpClient.PostAsync(requestUri, stringContent);
            httpClient.Dispose();
            return response;
        }
        public async Task<HttpResponseMessage> PutJsonAsync<T>(string requestUri, T content)
        {
            HttpClient httpClient = new HttpClient();
            string myContent = JsonConvert.SerializeObject(content);
            StringContent stringContent = new StringContent(myContent, Encoding.UTF8, "application/json");
            var response = await httpClient.PutAsync(requestUri, stringContent);
            httpClient.Dispose();
            return response;
        }
    }
}

 

step 7.Creating Data Access Layer for the Application

Right-click on ServerSideSPA.App project and then select Add >> New Folder and name the folder as DataAccess. We will be adding our class to handle database related operations inside this folder only.
 
Right click on DataAccess folder and select Add >> Class. Name your class EmployeeDataAccessLayer.cs. Open EmployeeDataAccessLayer.cs and put the following code into it.
using Microsoft.EntityFrameworkCore;  
using ServerSideSPA.App.Models;  
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Threading.Tasks;  
  
namespace ServerSideSPA.App.DataAccess  
{  
    public class EmployeeDataAccessLayer  
    {  
        myTestDBContext db = new myTestDBContext();  
  
        //To Get all employees details       
        public List<Employee> GetAllEmployees()  
        {  
            try  
            {  
                return db.Employee.AsNoTracking().ToList();  
            }  
            catch  
            {  
                throw;  
            }  
        }  
  
        //To Add new employee record         
        public void AddEmployee(Employee employee)  
        {  
            try  
            {  
                db.Employee.Add(employee);  
                db.SaveChanges();  
            }  
            catch  
            {  
                throw;  
            }  
        }  
  
        //To Update the records of a particluar employee        
        public void UpdateEmployee(Employee employee)  
        {  
            try  
            {  
                db.Entry(employee).State = EntityState.Modified;  
                db.SaveChanges();  
            }  
            catch  
            {  
                throw;  
            }  
        }  
  
        //Get the details of a particular employee        
        public Employee GetEmployeeData(int id)  
        {  
            try  
            {  
                var employee = db.Employee.Find(id);  
                db.Entry(employee).State = EntityState.Detached;  
                return employee;  
            }  
            catch  
            {  
                throw;  
            }  
        }  
  
        //To Delete the record of a particular employee        
        public void DeleteEmployee(int id)  
        {  
            try  
            {  
                Employee emp = db.Employee.Find(id);  
                db.Employee.Remove(emp);  
                db.SaveChanges();  
            }  
            catch  
            {  
                throw;  
            }  
        }  
  
        // To get the list of Cities  
        public List<Cities> GetCityData()  
        {  
            try  
            {  
                return db.Cities.ToList();  
            }  
            catch  
            {  
                throw;  
            }  
        }  
    }  
} ​
 
Here, we have defined the methods to handle database operations. GetAllEmployees will fetch all the employee data from the Employee table. Similarly, AddEmployee will create a new employee record and UpdateEmployee will update the record of an existing employee. GetEmployeeData will fetch the record of the employee corresponding to the employee ID passed to it and DeleteEmployee will delete the employee record corresponding to the employee id passed to it. GetCityData will fetch the list of all the cities from Cities table.

step 8.Creating the Service class

Right click on Services folder and select Add >> Class. Give the name of the class as “EmployeeService.cs” and click Add. This will add the EmployeeService class to the Services folder.
 
Open EmployeeService.cs and put the following code into it,
using ServerSideSPA.App.DataAccess;  
using ServerSideSPA.App.Models;  
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Threading.Tasks;  
  
namespace ServerSideSPA.App.Services  
{  
    public class EmployeeService  
    {  
        EmployeeDataAccessLayer objemployee = new EmployeeDataAccessLayer();  
  
        public Task<List<Employee>> GetEmployeeList()  
        {  
            return Task.FromResult(objemployee.GetAllEmployees());  
        }  
  
        public void Create(Employee employee)  
        {  
            objemployee.AddEmployee(employee);  
        }  
        public Task<Employee> Details(int id)  
        {  
            return Task.FromResult(objemployee.GetEmployeeData(id));  
        }  
  
        public void Edit(Employee employee)  
        {  
            objemployee.UpdateEmployee(employee);  
        }  
        public void Delete(int id)  
        {  
            objemployee.DeleteEmployee(id);  
        }  
        public Task<List<Cities>> GetCities()  
        {  
            return Task.FromResult(objemployee.GetCityData());  
        }  
    }  
}  
We will invoke the methods of EmployeeDataAccessLayer class from our service. The service will be injected into our components and the components will call the service methods to access the database.

At this point in time, the ServerSideSPA.App project has the following structure.

 

Configuring the Service

To make the service available to the components we need to configure it on the server side app. Open ServerSideSPA.App >> Startup.cs file. Add the following line inside the ConfigureServices method of Startup class.
  • services.AddSingleton<EmployeeService>(); 
Refer to the image below.
 
 
 
Now we will proceed to create our view component.

Creating the View Component

We will add the Razor page in ServerSideSPA.App/Pages folder. By default, we have “Counter” and “Fetch Data” pages provided in our application. These default pages will not affect our application but for the sake of this tutorial, we will delete fetchdata and counter pages from

ServerSideSPA.App/Pages folder.

Right-click on ServerSideSPA.App/Pages folder and then select Add >> New Item. An “Add New Item” dialog box will open, select "ASP.NET Core" from the left panel, then select “Razor Page” from templates panel and name it EmployeeData.cshtml. Click Add.


This will add an EmployeeData.cshtml page to the Pages folder. This razor page will have two files, EmployeeData.cshtml and EmployeeData.cshtml.cs.

Now, we will add codes to these pages.

EmployeeData.cshtml

Open EmployeeData.cshtml page and put the following code into it.
 
  1. @page "/fetchemployee"  
  2. @inherits EmployeeDataModel  
  3.   
  4. <h1>Employee Data</h1>  
  5. <p>This component demonstrates CRUD operation on Employee data</p>  
  6.   
  7. <div>  
  8.     <div style="float:left">  
  9.         <button class="btn btn-primary" onclick="@AddEmp">Add Employee</button>  
  10.     </div>  
  11.     <div style="float:right; width:40%;">  
  12.         <div class="col-sm-6" style="float:left">  
  13.             <input class="form-control" type="text" placeholder="Search" bind="@SearchString" />  
  14.         </div>  
  15.         <div>  
  16.             <button type="submit" class="btn btn-default btn-info" onclick="@FilterEmp">Filter</button>  
  17.         </div>  
  18.     </div>  
  19. </div>  
  20.   
  21. @if (empList == null)  
  22. {  
  23.     <p><em>Loading...</em></p>  
  24. }  
  25. else  
  26. {  
  27.     <table class='table'>  
  28.         <thead>  
  29.             <tr>  
  30.                 <th>ID</th>  
  31.                 <th>Name</th>  
  32.                 <th>Gender</th>  
  33.                 <th>Department</th>  
  34.                 <th>City</th>  
  35.             </tr>  
  36.         </thead>  
  37.         <tbody>  
  38.             @foreach (var emp in empList)  
  39.             {  
  40.                 <tr>  
  41.                     <td>@emp.EmployeeId</td>  
  42.                     <td>@emp.Name</td>  
  43.                     <td>@emp.Gender</td>  
  44.                     <td>@emp.Department</td>  
  45.                     <td>@emp.City</td>  
  46.                     <td>  
  47.                         <button class="btn btn-default" onclick="@(async () => await EditEmployee(@emp.EmployeeId))">Edit</button>  
  48.                         <button class="btn btn-danger" onclick="@(async () => await DeleteConfirm(@emp.EmployeeId))">Delete</button>  
  49.                     </td>  
  50.                 </tr>  
  51.             }  
  52.         </tbody>  
  53.     </table>  
  54.   
  55.     if (isAdd)  
  56.     {  
  57.         <div class="modal" tabindex="-1" style="display:block" role="dialog">  
  58.             <div class="modal-dialog">  
  59.                 <div class="modal-content">  
  60.                     <div class="modal-header">  
  61.                         <h3 class="modal-title">@modalTitle</h3>  
  62.                         <button type="button" class="close" onclick="@closeModal">  
  63.                             <span aria-hidden="true">X</span>  
  64.                         </button>  
  65.                     </div>  
  66.                     <div class="modal-body">  
  67.                         <form>  
  68.                             <div class="form-group">  
  69.                                 <label for="Name" class="control-label">Name</label>  
  70.                                 <input for="Name" class="form-control" bind="@emp.Name" />  
  71.                             </div>  
  72.                             <div class="form-group">  
  73.                                 <label asp-for="Gender" class="control-label">Gender</label>  
  74.                                 <select asp-for="Gender" class="form-control" bind="@emp.Gender">  
  75.                                     <option value="">-- Select Gender --</option>  
  76.                                     <option value="Male">Male</option>  
  77.                                     <option value="Female">Female</option>  
  78.                                 </select>  
  79.                             </div>  
  80.                             <div class="form-group">  
  81.                                 <label asp-for="Department" class="control-label">Department</label>  
  82.                                 <input asp-for="Department" class="form-control" bind="@emp.Department" />  
  83.                             </div>  
  84.                             <div class="form-group">  
  85.                                 <label asp-for="City" class="control-label">City</label>  
  86.                                 <select asp-for="City" class="form-control" bind="@emp.City">  
  87.                                     <option value="">-- Select City --</option>  
  88.                                     @foreach (var city in cityList)  
  89.                                     {  
  90.                                         <option value="@city.CityName">@city.CityName</option>  
  91.                                     }  
  92.                                 </select>  
  93.                             </div>  
  94.                         </form>  
  95.                     </div>  
  96.                     <div class="modal-footer">  
  97.                         <button class="btn btn-block btn-info" onclick="@(async () => await SaveEmployee())" data-dismiss="modal">Save</button>  
  98.                     </div>  
  99.                 </div>  
  100.             </div>  
  101.         </div>  
  102.     }  
  103.   
  104.     if (isDelete)  
  105.     {  
  106.         <div class="modal" tabindex="-1" style="display:block" role="dialog">  
  107.             <div class="modal-dialog">  
  108.                 <div class="modal-content">  
  109.                     <div class="modal-header">  
  110.                         <h3 class="modal-title">Delete Employee</h3>  
  111.                     </div>  
  112.                     <div class="modal-body">  
  113.                         <h4>Do you want to delete this employee ??</h4>  
  114.                         <table class="table">  
  115.                             <tr>  
  116.                                 <td>Name</td>  
  117.                                 <td>@emp.Name</td>  
  118.                             </tr>  
  119.                             <tr>  
  120.                                 <td>Gender</td>  
  121.                                 <td>@emp.Gender</td>  
  122.                             </tr>  
  123.                             <tr>  
  124.                                 <td>Department</td>  
  125.                                 <td>@emp.Department</td>  
  126.                             </tr>  
  127.                             <tr>  
  128.                                 <td>City</td>  
  129.                                 <td>@emp.City</td>  
  130.                             </tr>  
  131.                         </table>  
  132.                     </div>  
  133.                     <div class="modal-footer">  
  134.                         <button class="btn btn-danger" onclick="@(async () => await DeleteEmployee(emp.EmployeeId))" data-dismiss="modal">YES</button>  
  135.                         <button class="btn btn-warning" onclick="@closeModal">NO</button>  
  136.                     </div>  
  137.                 </div>  
  138.             </div>  
  139.         </div>  
  140.     }  
  141. }  

Let us understand this code. At the top we have defined the route of this page as “/fetchemployee”. This means if we append “/fetchemployee” to the root URL of the app, we will be redirected to this page.

We are also inheriting EmployeeDataModel class, which is defined in EmployeeData.cshtml.cs file. This will allow us to use the methods defined in EmployeeDataModel class.

After this, we have defined a button to add a new employee record. When clicked, this button will open a modal popup to handle the user inputs.

We have also defined a searchbox and corresponding button to filter the employee records based on employee name. If you enter an employee name and click on the Filter button, it will show all the employee record for which the name matches the value entered in the field. If we click on the Filter button without entering any value in the search box, it will return all the employee records.

The employee records returned from the database are stored in the empList variable. If the variable is not null then we will bind the values to a table to display the employee records in a tabular fashion. Each employee record will also have two action links, Edit to edit the employee record and Delete to delete the employee record.

To handle the user inputs we are using a form. We are using a single form for both Add Employee and Edit Employee functionality. The form is defined in a modal popup and the modal popup is displayed on the screen based on the value of a Boolean property isAdd. The value of this Boolean property is set in the code behind (.cshtml.cs) page.

The City dropdown list inside the form is binding to our Cities table in the database with the help of cityList variable. The cityList will be populated as the application boots up.

The form will have a Save button which will invoke SaveEmployee method, defined in the code behind file to Add or update an employee record.

Similar to Add modal popup, we also have a Delete modal popup. It will be a read-only modal and ask for a confirmation to delete an employee record. Upon clicking “Yes”, it will invoke the DeleteEmployee method to delete the employee record. 

EmployeeData.cshtml.cs

Open EmployeeData.cshtml.cs and put the following code into it.
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Linq;  
  4. using System.Threading.Tasks;  
  5. using Microsoft.AspNetCore.Blazor;  
  6. using Microsoft.AspNetCore.Blazor.Components;  
  7. using Microsoft.AspNetCore.Blazor.Services;  
  8. using ServerSideSPA.App.Models;  
  9. using ServerSideSPA.App.Services;  
  10.   
  11. namespace ServerSideSPA.App.Pages  
  12. {  
  13.     public class EmployeeDataModel : BlazorComponent  
  14.     {  
  15.         [Inject]  
  16.         protected EmployeeService employeeService { getset; }  
  17.   
  18.         protected List<Employee> empList;  
  19.         protected List<Cities> cityList = new List<Cities>();  
  20.         protected Employee emp = new Employee();  
  21.         protected string modalTitle { getset; }  
  22.         protected Boolean isDelete = false;  
  23.         protected Boolean isAdd = false;  
  24.   
  25.         protected string SearchString { getset; }  
  26.   
  27.         protected override async Task OnInitAsync()  
  28.         {  
  29.             await GetCities();  
  30.             await GetEmployee();  
  31.         }  
  32.   
  33.         protected async Task GetCities()  
  34.         {  
  35.             cityList = await employeeService.GetCities();  
  36.         }  
  37.   
  38.         protected async Task GetEmployee()  
  39.         {  
  40.             empList = await employeeService.GetEmployeeList();  
  41.         }  
  42.   
  43.         protected async Task FilterEmp()  
  44.         {  
  45.             await GetEmployee();  
  46.             if (SearchString != "")  
  47.             {  
  48.                 empList = empList.Where(x => x.Name.IndexOf(SearchString, StringComparison.OrdinalIgnoreCase) != -1).ToList();  
  49.             }  
  50.         }  
  51.   
  52.         protected void AddEmp()  
  53.         {  
  54.             emp = new Employee();  
  55.             this.modalTitle = "Add Employee";  
  56.             this.isAdd = true;  
  57.         }  
  58.   
  59.         protected async Task EditEmployee(int empID)  
  60.         {  
  61.             emp = await employeeService.Details(empID);  
  62.             this.modalTitle = "Edit Employee";  
  63.             this.isAdd = true;  
  64.         }  
  65.   
  66.         protected async Task SaveEmployee()  
  67.         {  
  68.             if (emp.EmployeeId != 0)  
  69.             {  
  70.                 await Task.Run(() =>  
  71.                 {  
  72.                     employeeService.Edit(emp);  
  73.                 });  
  74.             }  
  75.             else  
  76.             {  
  77.                 await Task.Run(() =>  
  78.                 {  
  79.                     employeeService.Create(emp);  
  80.                 });  
  81.             }  
  82.             this.isAdd = false;  
  83.             await GetEmployee();  
  84.         }  
  85.   
  86.         protected async Task DeleteConfirm(int empID)  
  87.         {  
  88.             emp = await employeeService.Details(empID);  
  89.             this.isDelete = true;  
  90.         }  
  91.   
  92.         protected async Task DeleteEmployee(int empID)  
  93.         {  
  94.             await Task.Run(() =>  
  95.             {  
  96.                 employeeService.Delete(empID);  
  97.             });  
  98.             this.isDelete = false;  
  99.             await GetEmployee();  
  100.         }  
  101.         protected void closeModal()  
  102.         {  
  103.             this.isAdd = false;  
  104.             this.isDelete = false;  
  105.         }  
  106.     }  
  107. }  

Let us understand this code. We have defined a class EmployeeDataModel that will hold all our methods that we will be using in EmployeeData.cshtml page.

We are injecting our EmployeeService to EmployeeDataModel class so that the client side methods can invoke our services.

The variables empList and cityList to hold the data from the Employee table and Cities table respectively. The variables are getting populated inside the OnInitAsync to make sure that the data is available to us as the page loads.

We will use the FilterEmp method to filter the employee data based on the employee name property. This property will ignore the text case of the search string and return all the records that match either fully or partially with the search string.

Clicking on “Add Employee” button will invoke the AddEmp method. It will initialize an empty instance of Employee model and set the value of isAdd Boolean flag to true. This will open a modal popup with a form, asking the user to enter a new employee record. Similarly, we have defined an EditEmployee method, which will fetch the record of the employee based on the employee id for which it is invoked. It will also set the value of isAdd to true to open the modal popup to edit the employee record.

The SaveEmployee method will check if it is invoked to add a new employee record or to edit an existing employee record. If the EmployeeId property is set then it is an “edit” request and we will invoke the Edit method of our service. If EmployeeId is not set then it is a “create” request and we will invoke the Create method of our service. We will then fetch the updated employee record by calling GetEmployee method and also set the value of isAdd to false, thus closing the modal popup.

The DeleteConfirm method is invoked by clicking the Delete button corresponding to an employee record. It will set the value of isDelete Boolean flag to true, which will display a Delete confirmation modal popup. Upon clicking YES inside this popup, DeleteEmployee method is invoked which will delete the employee record and set the isDelete Boolean flag to false to close the modal popup.

Adding Link to Navigation menu

The last step is to add the link to our “EmployeeData” page in the navigation menu, open ServerSideSPA.App/Shared/NavMenu.cshtml page and put the following code into it.
 
  1. <div class="top-row pl-4 navbar navbar-dark">  
  2.     <a class="navbar-brand" href="">ServerSideSPA</a>  
  3.     <button class="navbar-toggler" onclick=@ToggleNavMenu>  
  4.         <span class="navbar-toggler-icon"></span>  
  5.     </button>  
  6. </div>  
  7.   
  8. <div class=@(collapseNavMenu ? "collapse" : null) onclick=@ToggleNavMenu>  
  9.     <ul class="nav flex-column">  
  10.         <li class="nav-item px-3">  
  11.             <NavLink class="nav-link" href="" Match=NavLinkMatch.All>  
  12.                 <span class="oi oi-home" aria-hidden="true"></span> Home  
  13.             </NavLink>  
  14.         </li>  
  15.         <li class="nav-item px-3">  
  16.             <NavLink class="nav-link" href="fetchemployee">  
  17.                 <span class="oi oi-list-rich" aria-hidden="true"></span> Fetch employee  
  18.             </NavLink>  
  19.         </li>  
  20.     </ul>  
  21. </div>  
  22.   
  23. @functions {  
  24. bool collapseNavMenu = true;  
  25.   
  26. void ToggleNavMenu()  
  27. {  
  28.     collapseNavMenu = !collapseNavMenu;  
  29. }  
  30. }  

This completes our Single Page Application using server side Blazor.

Execution Demo

Press F5 to launch the application.

A web page will open as shown in the image below. The navigation menu on the left is showing navigation link for Employee data page.
 
 
 
Click on “Employee data” link, it will redirect to EmployeeData view. Here you can see all the employee data on the page. Notice the URL has “/fetchemployee” appended to it.
 
 

Click on Add Employee button to open “Add Employee” modal popup. Enter the data in all the fields and click on Save to create a new employee record.

 

This will create a new employee record and display the data in the View table. Add a few more records and the view will be similar as shown below.

 

Click on Edit button, it will again open the modal popup for editing the employee record. Edit the input fields and click on save to update the employee record.

 

To filter the records of the employee, enter the employee name in the search box and click on Filter button. The search text is case independent and the filter operation will return all the employee records matching the name entered in the search field. Refer to the image below.

 

If you click on the Delete button corresponding to the employee record, it will open a delete confirmation popup asking for a confirmation to delete the employee record.

 

Clicking on YES will delete the employee data and show the updated list of employees by refreshing the view table. 

Conclusion

We have created a server-side Blazor application using Entity Framework Core DB first approach with the help of Visual Studio 2017 and SQL Server 2017. We used a modal popup to handle user inputs via a form and implemented the search functionality on the employee records.

Please get the source code from Github and play around to get a better understanding.

You can also read other articles on my personal blog here.

See Also