Blazor Web Assembly 3.2 Add/Edit/Delete Fully Functional Application - Part One

Introduction

 
In this article we will create a fully functional Blazor site with Add/Edit/Delete and display features. This is the first part of the article and it will be focussed around creating .NET Core APIs and repository layers using Entity Framework Core.
 
We will be saving our application data in SQL Server.
 
Prerequisites
 
This article assumes you have a basic working knowledge of Blazor web assembly and .NET Core.
 
Read my previous article on creating custom Blazor components and reusing it on Razor pages.
 
Through this article, we will cover the following topics,
  • Creating Blazor Web assembly app, .NET Core hosted
  • Connecting to SQL Server and data retrieval using Entity Framework Core
  • Creating REST APIs and repository layer to save and read data
Output
 
Employee Home Page 
 
 
Employee Detail Page
 
 

Implementation

 
This project requires VS 2019 installed on your machine
 
Step 1 - Creating new Blazor web assembly project .NET Core hosted
 
Open Vs 2019 and create new Project and select Blazor Project Template. 
 
 
Check ASP.NET Core hosted check box. 
 
 
Solution Structure
 
VS will create a new project with solution structure as shown below.
 
 
Employee.Client project
 
This is a Blazor Web Assembly Project and all the client side code will reside in this project.
 
This will inculde the below items.
  1. Blazor components
  2. Razor pages
  3. Client side css libraries and Master Layout 
  4. Services (Services are used to call .NET Core Api)
The first part of the article is focused around building .NET CORE API which would be consumed by Blazor pages to bind and display data.
 
The details of Blazor data binding would be discussed in part two.
 
 
EmployeePortal.Server
 
This is the ASP.NET Core project. All our APIs and repositories will reside in this project.
 
It will also contain all the necessary configuration to connect to the SQL server.
 
 
EmployeePortal.Shared 
 
This Project will inculde data models and it will be shared by our client and server projects.
 
Step 2 - Connecting to SQL Server and data retrieval using Entity framework Core
 
Install EntityframeworkCore nudget packages as shown below.
 
 
Create a new Employee class in shared project.
 
This is our Data Model.
  1. [Table("Employee")]  
  2. public partial class Employee {  
  3.     public int EmployeeId {  
  4.         get;  
  5.         set;  
  6.     }  
  7.     [Required]  
  8.     [StringLength(50, ErrorMessage = "First name is too long.")]  
  9.     public string FirstName {  
  10.         get;  
  11.         set;  
  12.     }  
  13.     [Required]  
  14.     [StringLength(50, ErrorMessage = "Last name is too long.")]  
  15.     public string LastName {  
  16.         get;  
  17.         set;  
  18.     }  
  19.     [Required]  
  20.     [EmailAddress]  
  21.     public string Email {  
  22.         get;  
  23.         set;  
  24.     }  
  25.     public string Street {  
  26.         get;  
  27.         set;  
  28.     }  
  29.     public string Zip {  
  30.         get;  
  31.         set;  
  32.     }  
  33.     public string City {  
  34.         get;  
  35.         set;  
  36.     }  
  37.     public string PhoneNumber {  
  38.         get;  
  39.         set;  
  40.     }  
  41.     [StringLength(1000, ErrorMessage = "Comment length can't exceed 1000 characters.")]  
  42.     public string Comment {  
  43.         get;  
  44.         set;  
  45.     }  
  46. }  
Create a new Database in SQL Server Hrms
 
Create a new Employee as per the below schema.
 
Database Table script
  1. CREATE TABLE [dbo].[Employee](  
  2. [EmployeeId] [int] IDENTITY(1,1) NOT NULL,  
  3. [FirstName] [varchar](256) NULL,  
  4. [LastName] [varchar](256) NULL,  
  5. [Email] [varchar](256) NULL,  
  6. [Street] [varchar](256) NULL,  
  7. [Zip] [varchar](256) NULL,  
  8. [City] [varchar](256) NULL,  
  9. [PhoneNumber] [varchar](256) NULL,  
  10. [Comment] [varchar](256) NULL  
  11. ON [PRIMARY]  
  12. GO  
Configuring SQL connection string
 
Under app settings in EmployeePortal.Server project configure to connect to SQL Server 
  1. {  
  2.     "ConnectionStrings": {  
  3.         "DefaultConnection""Server=””;Database=”Hrms”;user="  
  4.         username ";password="  
  5.         password ";MultipleActiveResultSets=true;"  
  6.     },  
  7.     "Logging": {  
  8.         "LogLevel": {  
  9.             "Default""Information",  
  10.             "Microsoft""Warning",  
  11.             "Microsoft.Hosting.Lifetime""Information"  
  12.         }  
  13.     },  
  14.     "AllowedHosts""*"  
Create a new Database folder in Server Project and Add Below files
 
Employee Repository
 
The will contain all the method implementation to add/edit/get and delete employee data.
 
Register SQL connection and Employee Repository in Startup.cs file.
  1. public void ConfigureServices(IServiceCollection services) {  
  2.     services.AddDbContext < AppDbContext > (options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));  
  3.     services.AddControllersWithViews();  
  4.     services.AddRazorPages();  
  5.     services.AddScoped < IEmployeeRepository, EmployeeRepository > ();  
  6. }  
  7. public class EmployeeRepository: IEmployeeRepository {  
  8.     private readonly AppDbContext _appDbContext;  
  9.     public EmployeeRepository(AppDbContext appDbContext) {  
  10.         _appDbContext = appDbContext;  
  11.     }  
  12.     public IEnumerable < Employee > GetAllEmployees() {  
  13.         return _appDbContext.Employees.ToList();  
  14.     }  
  15.     public Employee AddEmployee(Employee employee) {  
  16.         var addedEntity = _appDbContext.Employees.Add(employee);  
  17.         _appDbContext.SaveChanges();  
  18.         return addedEntity.Entity;  
  19.     }  
  20.     public Employee GetEmployeeById(int employeeId) {  
  21.         return _appDbContext.Employees.FirstOrDefault(c => c.EmployeeId == employeeId);  
  22.     }  
  23.     public Employee UpdateEmployee(Employee employee) {  
  24.         var foundEmployee = _appDbContext.Employees.FirstOrDefault(e => e.EmployeeId == employee.EmployeeId);  
  25.         if (foundEmployee != null) {  
  26.             foundEmployee.City = employee.City;  
  27.             foundEmployee.Email = employee.Email;  
  28.             foundEmployee.FirstName = employee.FirstName;  
  29.             foundEmployee.LastName = employee.LastName;  
  30.             foundEmployee.PhoneNumber = employee.PhoneNumber;  
  31.             foundEmployee.Street = employee.Street;  
  32.             foundEmployee.Zip = employee.Zip;  
  33.             foundEmployee.Comment = employee.Comment;;  
  34.             _appDbContext.SaveChanges();  
  35.             return foundEmployee;  
  36.         }  
  37.         return null;  
  38.     }  
  39.     public void DeleteEmployee(int employeeId) {  
  40.         var foundEmployee = _appDbContext.Employees.FirstOrDefault(e => e.EmployeeId == employeeId);  
  41.         if (foundEmployee == nullreturn;  
  42.         _appDbContext.Employees.Remove(foundEmployee);  
  43.         _appDbContext.SaveChanges();  
  44.     }  
  45. }  
  46. }  
Employee Interface
 
The Interface contains method definitions of add/edit/get and delete employee data.
  1. public interface IEmployeeRepository {  
  2.     IEnumerable < Employee > GetAllEmployees();  
  3.     Employee AddEmployee(Employee employee);  
  4.     Employee GetEmployeeById(int employeeId);  
  5.     Employee UpdateEmployee(Employee employee);  
  6.     void DeleteEmployee(int employeeId);  
  7. }  
Appdbcontext
  1. public class AppDbContext: DbContext {  
  2.     public AppDbContext(DbContextOptions < AppDbContext > options): base(options) {}  
  3.     public DbSet < Employee > Employees {  
  4.         get;  
  5.         set;  
  6.     }  
  7. }  
Our Database Repository layer is ready to be consumed by .NET Core API. Lets go ahead and build the API.
 
Step 3 - Creating ,NET Core API
 
Add new Employee Controller in EmployeePortal.Server Project.
 
The controller has the below-mentioned API methods.
 
GetAllEmployees():Get method to get all Employess from DB.
 
CreateEmployee(); Post method takes employee object and validates model before saving final data in database.
 
GetEmployeeById:Get method to get specfic Employee.This method required EmployeeID as parameter.
 
UpdateEmployee:Put mehod use to update specific Employee. This method required EmployeeID as parameter.
 
DeleteEmployee:Delete method use to delete Employee.This method required EmployeeID as parameter.
  1. [Route("api/[controller]")]  
  2. [ApiController]  
  3. public class EmployeeController: Controller {  
  4.     private readonly IEmployeeRepository _employeeRepository;  
  5.     public EmployeeController(IEmployeeRepository employeeRepository) {  
  6.             _employeeRepository = employeeRepository;  
  7.         }  
  8.         [HttpGet]  
  9.     public IActionResult GetAllEmployees() {  
  10.             return Ok(_employeeRepository.GetAllEmployees());  
  11.         }  
  12.         [HttpPost]  
  13.     public IActionResult CreateEmployee([FromBody] Employee employee) {  
  14.             if (employee == nullreturn BadRequest();  
  15.             if (employee.FirstName == string.Empty || employee.LastName == string.Empty) {  
  16.                 ModelState.AddModelError("Name/FirstName""The name or first name shouldn't be empty");  
  17.             }  
  18.             if (!ModelState.IsValid) return BadRequest(ModelState);  
  19.             var createdEmployee = _employeeRepository.AddEmployee(employee);  
  20.             return Created("employee", createdEmployee);  
  21.         }  
  22.         [HttpGet("{employeeId}")]  
  23.     public IActionResult GetEmployeeById(int employeeId) {  
  24.             return Ok(_employeeRepository.GetEmployeeById(employeeId));  
  25.         }  
  26.         [HttpPut]  
  27.     public IActionResult UpdateEmployee([FromBody] Employee employee) {  
  28.             if (employee == nullreturn BadRequest();  
  29.             if (employee.FirstName == string.Empty || employee.LastName == string.Empty) {  
  30.                 ModelState.AddModelError("Name/FirstName""The name or first name shouldn't be empty");  
  31.             }  
  32.             if (!ModelState.IsValid) return BadRequest(ModelState);  
  33.             var employeeToUpdate = _employeeRepository.GetEmployeeById(employee.EmployeeId);  
  34.             if (employeeToUpdate == nullreturn NotFound();  
  35.             _employeeRepository.UpdateEmployee(employee);  
  36.             return NoContent(); //success  
  37.         }  
  38.         [HttpDelete("{id}")]  
  39.     public IActionResult DeleteEmployee(int id) {  
  40.         if (id == 0) return BadRequest();  
  41.         var employeeToDelete = _employeeRepository.GetEmployeeById(id);  
  42.         if (employeeToDelete == nullreturn NotFound();  
  43.         _employeeRepository.DeleteEmployee(id);  
  44.         return NoContent(); //success  
  45.     }  
  46. }  
Our API layer is ready to be consumed by Blazor Client. Api data biinding in Blazor will be covered in part 2 of the article.
 

Summary

 
Through this article we have learned how to create Blazor web assembly projects hosted in  .NET Core  and also build data access layer using Entity Framework Core to retrieve and save our application data in SQL Server.
 
In our next article we will create Blazor Razor components and build a user interface to display data from APIs and save user data back to SQL Server.
 
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!