Blazor is a new framework built by Microsoft for creating interactive client-side web UI with .NET codebase. We can write both client-side and server-side code in C#.NET itself. I have already written three articles about Blazor server on C# Corner. Please refer to below articles for more basics about Blazor framework.
- Create A Simple Blazor Server Application With .NET Core 3.0 (https://answerguruji.blogspot.com/2019/11/create-simple-blazor-server-application.html)
- Create a Single Page App with Blazor Server and Entity Framework Core 3.0 (https://answerguruji.blogspot.com/2019/11/create-single-page-app-with-blazor.html)
- Combine SQL-DB and MongoDB In Same Blazor App (https://answerguruji.blogspot.com/2019/11/combine-sql-db-and-mongodb-in-same.html)
Dapper is a micro ORM (Object Relational Mapper) which helps to map the native query output to a domain class. It is a high-performance data access system built by StackOverflow team and released as open source. If your project prefers writing stored procedures or writing raw SQL queries instead of using a full-fledged ORM tools like EntityFramework, then Dapper is a better choice for you. Using Dapper, it is very easy to execute an SQL query against database and get the result mapped to C# domain class.
We will create a single page application in Blazor with two entities City and Employee. We will see all CRUD actions with these City and Employee entities. We will use raw SQL queries in City and stored procedures in Employee. We can see all the actions step by step.
Create database, tables and stored procedures in SQL server
Please use below SQL script to create new database, tables and stored procedures. As I told earlier, we will use these stored procedures for fetching and storing employee data using Dapper.
- USE master
- CREATE DATABASE SarathlalDb;
- GO
- USE SarathlalDb
- CREATE TABLE [dbo].[City] (
- [Id] INT IDENTITY (1, 1) NOT NULL,
- [Name] NVARCHAR (250) NULL,
- [State] NVARCHAR (250) NULL,
- PRIMARY KEY CLUSTERED ([Id] ASC)
- );
- GO
- CREATE TABLE [dbo].[Employees] (
- [Id] INT IDENTITY (1, 1) NOT NULL,
- [Name] NVARCHAR (250) NULL,
- [Department] NVARCHAR (250) NULL,
- [Designation] NVARCHAR (250) NULL,
- [Company] NVARCHAR (250) NULL,
- [CityId] INT NULL,
- CONSTRAINT [PK_Employees] PRIMARY KEY CLUSTERED ([Id] ASC)
- );
- GO
- CREATE PROCEDURE [dbo].Add_Employee
- @Name NVARCHAR(250),
- @Department NVARCHAR(250),
- @Designation NVARCHAR(250),
- @Company NVARCHAR(250),
- @CityId INT
- AS
- INSERT INTO dbo.Employees (Name,Department,Designation,Company,CityId)
- VALUES (@Name,@Department,@Designation,@Company,@CityId)
- GO
- CREATE PROCEDURE [dbo].Delete_Employee
- @Id INT
- AS
- DELETE FROM dbo.Employees WHERE Id = @Id
- GO
- CREATE PROCEDURE [dbo].[Get_AllEmployees]
- AS
- SELECT emp.*,c.Name CityName FROM dbo.Employees emp LEFT JOIN dbo.City c ON emp.CityId = c.Id ORDER BY emp.Name
- GO
- CREATE PROCEDURE [dbo].Get_SingleEmployee
- @Id INT
- AS
- SELECT emp.*,c.Name CityName from dbo.Employees emp LEFT JOIN dbo.City c ON emp.CityId = c.Id WHERE emp.Id = @Id
- GO
- CREATE PROCEDURE [dbo].Update_Employee
- @Id INT,
- @Name VARCHAR(250),
- @Department VARCHAR(250),
- @Designation VARCHAR(250),
- @Company VARCHAR(250),
- @CityId INT
- AS
- UPDATE dbo.Employees SET Name = @Name, Department = @Department, Designation = @Designation, Company = @Company, CityId = @CityId Where Id = @Id
- GO
Create Blazor application in Visual Studio 2019
Open Visual Studio 2019 and choose Blazor server template to create new project. Make sure, you have chosen ASP.NET Core 3.0 template.
We must install below packages to perform database operations using Dapper.
- “Dapper” and
- “Microsoft.Data.SqlClient”
Microsoft.Data.SqlClient is a new package, which supports both .NET and .NET Core framework. You can refer to below Microsoft document for more details about this package.
We can create a new class “SqlConnectionConfiguration” to fetch SQL connection string from appsettings.json configuration file. We will create all C# classes and services under “Data” folder.
SqlConnectionConfiguration.cs
- namespace BlazorDapperSPA.Data
- {
- public class SqlConnectionConfiguration
- {
- public SqlConnectionConfiguration(string value) => Value = value;
- public string Value { get; }
- }
- }
We can add connection string in appsettings.json file.
appsettings.json
- {
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft": "Warning",
- "Microsoft.Hosting.Lifetime": "Information"
- }
- },
- "AllowedHosts": "*",
- "ConnectionStrings": {
- "SqlDbContext": "Server=MURUGAN;Database=SarathlalDb;Trusted_Connection=True;MultipleActiveResultSets=true"
- }
- }
Create “City” class with below properties.
City.cs
- namespace BlazorDapperSPA.Data
- {
- public class City
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public string State { get; set; }
- }
- }
Create “Employee” class with below properties.
Employee.cs
- namespace BlazorDapperSPA.Data
- {
- public class Employee
- {
- public int Id { get; set; }
- public string Name { get; set; }
- public string Department { get; set; }
- public string Designation { get; set; }
- public string Company { get; set; }
- public string CityId { get; set; }
- }
- }
We need an “EmployeeModel” class along with Employee class. Because, we need City name in employee list component. We will join Employee table and City table and fetch the City name from City table along with other Employee table details. We can inherit Employee class inside the EmployeeModel class to leverage existing properties from Employee class.
EmployeeModel.cs
- namespace BlazorDapperSPA.Data
- {
- public class EmployeeModel : Employee
- {
- public string CityName { get; set; }
- }
- }
We can create an “ICityService” interface and declare below method signatures.
ICityService.cs
- using System.Collections.Generic;
- using System.Threading.Tasks;
- namespace BlazorDapperSPA.Data
- {
- public interface ICityService
- {
- Task<IEnumerable<City>> GetCities();
- Task<bool> CreateCity(City city);
- Task<bool> EditCity(int id, City city);
- Task<City> SingleCity(int id);
- Task<bool> DeleteCity(int id);
- }
- }
We can inherit above interface in new class “CityService” and implement methods.
CityService.cs
- using Dapper;
- using Microsoft.Data.SqlClient;
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Threading.Tasks;
- namespace BlazorDapperSPA.Data
- {
- public class CityService : ICityService
- {
- private readonly SqlConnectionConfiguration _configuration;
- public CityService(SqlConnectionConfiguration configuration)
- {
- _configuration = configuration;
- }
- public async Task<bool> CreateCity(City city)
- {
- using (var conn = new SqlConnection(_configuration.Value))
- {
- const string query = @"insert into dbo.City (Name,State) values (@Name,@State)";
- if (conn.State == ConnectionState.Closed)
- conn.Open();
- try
- {
- await conn.ExecuteAsync(query, new { city.Name, city.State }, commandType: CommandType.Text);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- finally
- {
- if (conn.State == ConnectionState.Open)
- conn.Close();
- }
- }
- return true;
- }
- public async Task<bool> DeleteCity(int id)
- {
- using (var conn = new SqlConnection(_configuration.Value))
- {
- const string query = @"delete from dbo.City where Id=@Id";
- if (conn.State == ConnectionState.Closed)
- conn.Open();
- try
- {
- await conn.ExecuteAsync(query, new { id }, commandType: CommandType.Text);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- finally
- {
- if (conn.State == ConnectionState.Open)
- conn.Close();
- }
- }
- return true;
- }
- public async Task<bool> EditCity(int id, City city)
- {
- using (var conn = new SqlConnection(_configuration.Value))
- {
- const string query = @"update dbo.City set Name = @Name, State = @State where Id=@Id";
- if (conn.State == ConnectionState.Closed)
- conn.Open();
- try
- {
- await conn.ExecuteAsync(query, new { city.Name, city.State, id }, commandType: CommandType.Text);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- finally
- {
- if (conn.State == ConnectionState.Open)
- conn.Close();
- }
- }
- return true;
- }
- public async Task<IEnumerable<City>> GetCities()
- {
- IEnumerable<City> cities;
- using (var conn = new SqlConnection(_configuration.Value))
- {
- const string query = @"select * from dbo.City";
- if (conn.State == ConnectionState.Closed)
- conn.Open();
- try
- {
- cities = await conn.QueryAsync<City>(query);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- finally
- {
- if (conn.State == ConnectionState.Open)
- conn.Close();
- }
- }
- return cities;
- }
- public async Task<City> SingleCity(int id)
- {
- City city = new City();
- using (var conn = new SqlConnection(_configuration.Value))
- {
- const string query = @"select * from dbo.City where Id =@Id";
- if (conn.State == ConnectionState.Closed)
- conn.Open();
- try
- {
- city = await conn.QueryFirstOrDefaultAsync<City>(query, new { id }, commandType: CommandType.Text);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- finally
- {
- if (conn.State == ConnectionState.Open)
- conn.Close();
- }
- }
- return city;
- }
- }
- }
We have added all logic for City entity in above class. We have used native SQL queries with Dapper.
Create an “IEmployeeService” interface and declare below methods.
IEmployeeService.cs
- using System.Collections.Generic;
- using System.Threading.Tasks;
- namespace BlazorDapperSPA.Data
- {
- public interface IEmployeeService
- {
- Task<IEnumerable<EmployeeModel>> GetEmployees();
- Task<bool> CreateEmployee(Employee employee);
- Task<bool> EditEmployee(int id, EmployeeModel employee);
- Task<EmployeeModel> SingleEmployee(int id);
- Task<bool> DeleteEmployee(int id);
- }
- }
We can inherit above interface in new class “EmployeeService” and implement all methods.
EmployeeService.cs
- using Dapper;
- using Microsoft.Data.SqlClient;
- using System;
- using System.Collections.Generic;
- using System.Data;
- using System.Threading.Tasks;
- namespace BlazorDapperSPA.Data
- {
- public class EmployeeService : IEmployeeService
- {
- private readonly SqlConnectionConfiguration _configuration;
- public EmployeeService(SqlConnectionConfiguration configuration)
- {
- _configuration = configuration;
- }
- public async Task<bool> CreateEmployee(Employee employee)
- {
- var parameters = new DynamicParameters();
- parameters.Add("Name", employee.Name, DbType.String);
- parameters.Add("Department", employee.Department, DbType.String);
- parameters.Add("Designation", employee.Designation, DbType.String);
- parameters.Add("Company", employee.Company, DbType.String);
- parameters.Add("CityId", employee.CityId, DbType.Int32);
- using (var conn = new SqlConnection(_configuration.Value))
- {
- if (conn.State == ConnectionState.Closed)
- conn.Open();
- try
- {
- await conn.ExecuteAsync("Add_Employee", parameters, commandType: CommandType.StoredProcedure);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- finally
- {
- if (conn.State == ConnectionState.Open)
- conn.Close();
- }
- }
- return true;
- }
- public async Task<bool> DeleteEmployee(int id)
- {
- var parameters = new DynamicParameters();
- parameters.Add("Id", id, DbType.Int32);
- using (var conn = new SqlConnection(_configuration.Value))
- {
- if (conn.State == ConnectionState.Closed)
- conn.Open();
- try
- {
- await conn.ExecuteAsync("Delete_Employee", parameters, commandType: CommandType.StoredProcedure);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- finally
- {
- if (conn.State == ConnectionState.Open)
- conn.Close();
- }
- }
- return true;
- }
- public async Task<bool> EditEmployee(int id, EmployeeModel employee)
- {
- var parameters = new DynamicParameters();
- parameters.Add("Id", id, DbType.Int32);
- parameters.Add("Name", employee.Name, DbType.String);
- parameters.Add("Department", employee.Department, DbType.String);
- parameters.Add("Designation", employee.Designation, DbType.String);
- parameters.Add("Company", employee.Company, DbType.String);
- parameters.Add("CityId", employee.CityId, DbType.Int32);
- using (var conn = new SqlConnection(_configuration.Value))
- {
- if (conn.State == ConnectionState.Closed)
- conn.Open();
- try
- {
- await conn.ExecuteAsync("Update_Employee", parameters, commandType: CommandType.StoredProcedure);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- finally
- {
- if (conn.State == ConnectionState.Open)
- conn.Close();
- }
- }
- return true;
- }
- public async Task<IEnumerable<EmployeeModel>> GetEmployees()
- {
- IEnumerable<EmployeeModel> employees;
- using (var conn = new SqlConnection(_configuration.Value))
- {
- if (conn.State == ConnectionState.Closed)
- conn.Open();
- try
- {
- employees = await conn.QueryAsync<EmployeeModel>("Get_AllEmployees", commandType: CommandType.StoredProcedure);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- finally
- {
- if (conn.State == ConnectionState.Open)
- conn.Close();
- }
- }
- return employees;
- }
- public async Task<EmployeeModel> SingleEmployee(int id)
- {
- var parameters = new DynamicParameters();
- parameters.Add("Id", id, DbType.Int32);
- EmployeeModel employee = new EmployeeModel();
- using (var conn = new SqlConnection(_configuration.Value))
- {
- if (conn.State == ConnectionState.Closed)
- conn.Open();
- try
- {
- employee = await conn.QueryFirstOrDefaultAsync<EmployeeModel>("Get_SingleEmployee", parameters, commandType: CommandType.StoredProcedure);
- }
- catch (Exception ex)
- {
- throw ex;
- }
- finally
- {
- if (conn.State == ConnectionState.Open)
- conn.Close();
- }
- }
- return employee;
- }
- }
- }
We have added all the logic for Employee entity in above class. We have used stored procedures for CURD operations with Dapper.
We can register the ICityService and IEmployeeService inside the “ConfigureServices” of Startup class.
We have enabled the detailed error for Blazor server application also.
ConfigureServices in Startup.cs class
- services.AddRazorPages();
- services.AddServerSideBlazor();
- services.AddSingleton<WeatherForecastService>();
- services.AddScoped<IEmployeeService, EmployeeService>();
- services.AddScoped<ICityService, CityService>();
- var sqlConnectionConfiguration = new SqlConnectionConfiguration(Configuration.GetConnectionString("SqlDbContext"));
- services.AddSingleton(sqlConnectionConfiguration);
- services.AddServerSideBlazor(o => o.DetailedErrors = true);
Create Blazor components for CRUD operations
We can create all components for City and Employee inside the “Pages” folder
ListCities.razor
- @using BlazorDapperSPA.Data
- @page "/listcities"
- @inject ICityService CityService
- <h2>City Details</h2>
- <p>
- <a href="/addcity">Create New City</a>
- </p>
- @if (cities == null)
- {
- <img src="./basicloader.gif" />
- }
- else
- {
- <table class='table'>
- <thead>
- <tr>
- <th>Name</th>
- <th>State</th>
- </tr>
- </thead>
- <tbody>
- @foreach (var city in cities)
- {
- <tr>
- <td>@city.Name</td>
- <td>@city.State</td>
- <td>
- <a href='/editcity/@city.Id'>Edit</a>
- <a href='/deletecity/@city.Id'>Delete</a>
- </td>
- </tr>
- }
- </tbody>
- </table>
- }
- @code {
- IEnumerable<City> cities;
- protected override async Task OnInitializedAsync()
- {
- cities = await CityService.GetCities();
- }
- }
AddCity.razor
- @using BlazorDapperSPA.Data
- @page "/addcity"
- @inject NavigationManager NavigationManager
- @inject ICityService CityService
- <h2>Create City</h2>
- <hr />
- <form>
- <div class="row">
- <div class="col-md-8">
- <div class="form-group">
- <label for="Name" class="control-label">Name</label>
- <input for="Name" class="form-control" @bind="@city.Name" />
- </div>
- <div class="form-group">
- <label for="State" class="control-label">State</label>
- <input for="State" class="form-control" @bind="@city.State" />
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-md-4">
- <div class="form-group">
- <input type="button" class="btn btn-primary" @onclick="@CreateCity" value="Save" />
- <input type="button" class="btn" @onclick="@Cancel" value="Cancel" />
- </div>
- </div>
- </div>
- </form>
- @code {
- City city = new City();
- protected async Task CreateCity()
- {
- await CityService.CreateCity(city);
- NavigationManager.NavigateTo("listcities");
- }
- void Cancel()
- {
- NavigationManager.NavigateTo("listcities");
- }
- }
EditCity.razor
- @using BlazorDapperSPA.Data
- @page "/editcity/{id:int}"
- @inject NavigationManager NavigationManager
- @inject ICityService CityService
- <h2>Edit City</h2>
- <hr />
- <form>
- <div class="row">
- <div class="col-md-8">
- <div class="form-group">
- <label for="Name" class="control-label">Name</label>
- <input for="Name" class="form-control" @bind="@city.Name" />
- </div>
- <div class="form-group">
- <label for="State" class="control-label">State</label>
- <input for="State" class="form-control" @bind="@city.State" />
- </div>
- </div>
- </div>
- <div class="row">
- <div class="form-group">
- <input type="button" class="btn btn-primary" @onclick="@UpdateCity" value="Update" />
- <input type="button" class="btn" @onclick="@Cancel" value="Cancel" />
- </div>
- </div>
- </form>
- @code {
- [Parameter]
- public int id { get; set; }
- City city = new City();
- protected override async Task OnInitializedAsync()
- {
- city = await CityService.SingleCity(id);
- }
- protected async Task UpdateCity()
- {
- await CityService.EditCity(id, city);
- NavigationManager.NavigateTo("listcities");
- }
- void Cancel()
- {
- NavigationManager.NavigateTo("listcities");
- }
- }
DeleteCity.razor
- @using BlazorDapperSPA.Data
- @page "/deletecity/{id:int}"
- @inject NavigationManager NavigationManager
- @inject ICityService CityService
- <h2>Confirm Delete</h2>
- <p>Are you sure you want to delete this City with Id :<b> @id</b></p>
- <br />
- <div class="col-md-4">
- <table class="table">
- <tr>
- <td>Name</td>
- <td>@city.Name</td>
- </tr>
- <tr>
- <td>State</td>
- <td>@city.State</td>
- </tr>
- </table>
- <div class="form-group">
- <input type="button" value="Delete" @onclick="@Delete" class="btn btn-primary" />
- <input type="button" value="Cancel" @onclick="@Cancel" class="btn" />
- </div>
- </div>
- @code {
- [Parameter]
- public int id { get; set; }
- City city = new City();
- protected override async Task OnInitializedAsync()
- {
- city = await CityService.SingleCity(id);
- }
- protected async Task Delete()
- {
- await CityService.DeleteCity(id);
- NavigationManager.NavigateTo("listcities");
- }
- void Cancel()
- {
- NavigationManager.NavigateTo("listcities");
- }
- }
We can create component files for Employee CRUD actions
ListEmployees.razor
- @using BlazorDapperSPA.Data
- @page "/listemployees"
- @inject IEmployeeService EmployeeService
- <h2>Employee Details</h2>
- <p>
- <a href="/addemployee">Create New Employee</a>
- </p>
- @if (employees == null)
- {
- <img src="./basicloader.gif" />
- }
- else
- {
- <table class='table'>
- <thead>
- <tr>
- <th>Name</th>
- <th>Department</th>
- <th>Designation</th>
- <th>Company</th>
- <th>City</th>
- </tr>
- </thead>
- <tbody>
- @foreach (var employee in employees)
- {
- <tr>
- <td>@employee.Name</td>
- <td>@employee.Department</td>
- <td>@employee.Designation</td>
- <td>@employee.Company</td>
- <td>@employee.CityName</td>
- <td>
- <a href='/editemployee/@employee.Id'>Edit</a>
- <a href='/deleteemployee/@employee.Id'>Delete</a>
- </td>
- </tr>
- }
- </tbody>
- </table>
- }
- @code {
- IEnumerable<EmployeeModel> employees;
- protected override async Task OnInitializedAsync()
- {
- employees = await EmployeeService.GetEmployees();
- }
- }
AddEmployee.razor
- @using BlazorDapperSPA.Data
- @page "/addemployee"
- @inject NavigationManager NavigationManager
- @inject IEmployeeService EmployeeService
- @inject ICityService CityService
- <h2>Create Employee</h2>
- <hr />
- <form>
- <div class="row">
- <div class="col-md-8">
- <div class="form-group">
- <label for="Name" class="control-label">Name</label>
- <input for="Name" class="form-control" @bind="@employee.Name" />
- </div>
- <div class="form-group">
- <label for="Department" class="control-label">Department</label>
- <input for="Department" class="form-control" @bind="@employee.Department" />
- </div>
- <div class="form-group">
- <label for="Designation" class="control-label">Designation</label>
- <input for="Designation" class="form-control" @bind="@employee.Designation" />
- </div>
- <div class="form-group">
- <label for="Company" class="control-label">Company</label>
- <input for="Company" class="form-control" @bind="@employee.Company" />
- </div>
- <div class="form-group">
- <label for="City" class="control-label">City</label>
- <select for="City" class="form-control" @bind="@employee.CityId">
- <option value="">-- Select City --</option>
- @foreach (var city in cities)
- {
- <option value="@city.Id">@city.Name</option>
- }
- </select>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="col-md-4">
- <div class="form-group">
- <input type="button" class="btn btn-primary" @onclick="@CreateEmployee" value="Save" />
- <input type="button" class="btn" @onclick="@Cancel" value="Cancel" />
- </div>
- </div>
- </div>
- </form>
- @code {
- Employee employee = new Employee();
- IEnumerable<City> cities = new List<City>();
- protected override async Task OnInitializedAsync()
- {
- cities = await CityService.GetCities();
- }
- protected async Task CreateEmployee()
- {
- await EmployeeService.CreateEmployee(employee);
- NavigationManager.NavigateTo("listemployees");
- }
- void Cancel()
- {
- NavigationManager.NavigateTo("listemployees");
- }
- }
EditEmployee.razor
- @using BlazorDapperSPA.Data
- @page "/editemployee/{id:int}"
- @inject NavigationManager NavigationManager
- @inject IEmployeeService EmployeeService
- @inject ICityService CityService
- <h2>Edit Employee</h2>
- <hr />
- <form>
- <div class="row">
- <div class="col-md-8">
- <div class="form-group">
- <label for="Name" class="control-label">Name</label>
- <input for="Name" class="form-control" @bind="@employee.Name" />
- </div>
- <div class="form-group">
- <label for="Department" class="control-label">Department</label>
- <input for="Department" class="form-control" @bind="@employee.Department" />
- </div>
- <div class="form-group">
- <label for="Designation" class="control-label">Designation</label>
- <input for="Designation" class="form-control" @bind="@employee.Designation" />
- </div>
- <div class="form-group">
- <label for="Company" class="control-label">Company</label>
- <input for="Company" class="form-control" @bind="@employee.Company" />
- </div>
- <div class="form-group">
- <label for="City" class="control-label">City</label>
- <select for="City" class="form-control" @bind="@employee.CityId">
- <option value="">-- Select City --</option>
- @foreach (var city in cities)
- {
- <option value="@city.Id">@city.Name</option>
- }
- </select>
- </div>
- </div>
- </div>
- <div class="row">
- <div class="form-group">
- <input type="button" class="btn btn-primary" @onclick="@UpdateEmployee" value="Update" />
- <input type="button" class="btn" @onclick="@Cancel" value="Cancel" />
- </div>
- </div>
- </form>
- @code {
- [Parameter]
- public int id { get; set; }
- EmployeeModel employee = new EmployeeModel();
- IEnumerable<City> cities = new List<City>();
- protected override async Task OnInitializedAsync()
- {
- cities = await CityService.GetCities();
- employee = await EmployeeService.SingleEmployee(id);
- }
- protected async Task UpdateEmployee()
- {
- await EmployeeService.EditEmployee(id, employee);
- NavigationManager.NavigateTo("listemployees");
- }
- void Cancel()
- {
- NavigationManager.NavigateTo("listemployees");
- }
- }
DeleteEmployee.razor
- @using BlazorDapperSPA.Data
- @page "/deleteemployee/{id:int}"
- @inject NavigationManager NavigationManager
- @inject IEmployeeService EmployeeService
- <h2>Confirm Delete</h2>
- <p>Are you sure you want to delete this Employee with Id :<b> @id</b></p>
- <br />
- <div class="col-md-4">
- <table class="table">
- <tr>
- <td>Name</td>
- <td>@employee.Name</td>
- </tr>
- <tr>
- <td>Department</td>
- <td>@employee.Department</td>
- </tr>
- <tr>
- <td>Designation</td>
- <td>@employee.Designation</td>
- </tr>
- <tr>
- <td>Company</td>
- <td>@employee.Company</td>
- </tr>
- <tr>
- <td>City</td>
- <td>@employee.CityName</td>
- </tr>
- </table>
- <div class="form-group">
- <input type="button" value="Delete" @onclick="@Delete" class="btn btn-primary" />
- <input type="button" value="Cancel" @onclick="@Cancel" class="btn" />
- </div>
- </div>
- @code {
- [Parameter]
- public int id { get; set; }
- EmployeeModel employee = new EmployeeModel();
- protected override async Task OnInitializedAsync()
- {
- employee = await EmployeeService.SingleEmployee(id);
- }
- protected async Task Delete()
- {
- await EmployeeService.DeleteEmployee(id);
- NavigationManager.NavigateTo("listemployees");
- }
- void Cancel()
- {
- NavigationManager.NavigateTo("listemployees");
- }
- }
We can modify the “NavMenu” shared component with routing to City and Employee details.
NavMenu.razor
- <div class="top-row pl-4 navbar navbar-dark">
- <a class="navbar-brand" href="">Blazor with Dapper</a>
- <button class="navbar-toggler" @onclick="ToggleNavMenu">
- <span class="navbar-toggler-icon"></span>
- </button>
- </div>
- <div class="@NavMenuCssClass" @onclick="ToggleNavMenu">
- <ul class="nav flex-column">
- <li class="nav-item px-3">
- <NavLink class="nav-link" href="" Match="NavLinkMatch.All">
- <span class="oi oi-home" aria-hidden="true"></span> Home
- </NavLink>
- </li>
- <li class="nav-item px-3">
- <NavLink class="nav-link" href="listcities">
- <span class="oi oi-list-rich" aria-hidden="true"></span> City data
- </NavLink>
- </li>
- <li class="nav-item px-3">
- <NavLink class="nav-link" href="listemployees">
- <span class="oi oi-list-rich" aria-hidden="true"></span> Employee data
- </NavLink>
- </li>
- </ul>
- </div>
- @code {
- bool collapseNavMenu = true;
- string NavMenuCssClass => collapseNavMenu ? "collapse" : null;
- void ToggleNavMenu()
- {
- collapseNavMenu = !collapseNavMenu;
- }
- }
We have completed the entire coding. We can run the application.
We can create a new City by clicking “City data” menu link and click “Create New City” hyper link.
After saving the City details, we can click “Employee data” menu link and click “Create New Employee” hyper link to create new employee data.
You can notice that, already saved city data is shown in the dropdown.
You can see the saved employee data in a grid with Edit and Delete hyper link.
You can perform other CRUD actions like Edit or Delete as well.
No comments:
Post a Comment