In this article, we will learn what Blazor is and how we can set up Blazor by making a basic CRUD Application with Entity Framework Core Code first approach in .Net 5 (the latest version).
Prerequisites
Install the latest .NET 5.0 SDK from here.
Install the latest version of Visual Studio 2019 from here.
What we are going to cover in this?
What is Blazor and why it is exciting for C# Developers?
Difference between Blazor Server — Blazor Web Assembly
Setup the CRUD App using Blazor
Run and Test
What is Blazor and why is it exciting for C# Developers?
Blazor is a .NET web system that runs in the program. Think Angular or React however controlled by C# and Razor. Designers make Blazor applications utilizing a combination of C#, Razor, and HTML. These applications execute .NET congregations utilizing the Mono .NET runtime carried out through WebAssembly. Blazor utilizes the most recent web guidelines and requires no extra modules or additional items to run, this is not another Silverlight.
Blazor Server App
In the worker side facilitating model (Blazor Server-Side), Blazor is executed on the worker from inside an ASP.NET Core application. UI refreshes, occasion dealing with, and JavaScript brings are taken care of over a SignalR association.
Blazor also supports features of the SPA(Single Page Application) framework such as,
Routing
Layouts
Forms and validation
JavaScript interop
Build on save during development
Server-side rendering
Dependency Injection
Blazor Server-Side — Fig
Blazor Web Assembly
In the customer-side model (Blazor WebAssembly), the Blazor application, its conditions, and the .NET runtime are downloaded to the program, and the application is executed straightforwardly on the program UI string. All UI updates and occasions taking care of occur inside a similar cycle.
Blazor WASM Model-Fig
Setup
Create a Blazor Server App.
Fig-1
Add the project name for your Application
Fig-2
Make sure you have .Net 5.0 installed in your machine and then it will automatically be added in the dropdown select target framework as .Net 5.0
FIg-3
A basic scaffolded template will generate here is the project structure.
Fig-4
Create a class in the Data folder to act as a table in the database to store all our CRUD Operations.
Employee.cs
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Threading.Tasks;
namespace BlazorCRUD.Data
{
public class Employee
{
[Key]
public int Id { get; set; }
public string EmployeName { get; set; }
public string Gender { get; set; }
public string City { get; set; }
public string Designation { get; set; }
}
}
Create a DB context file to set up the configuration with Database.
AppDbContext.cs
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
namespace BlazorCRUD.Data
{
public class AppDBContext : DbContext
{
public AppDBContext(DbContextOptions<AppDBContext> options) : base(options)
{
}
public DbSet<Employee> Employees { get; set; }
}
}
Create an employee service with all the business logic inside this service.
Setup a connection string in the appsettings.json file.
appsettings.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"myconn": "server= Your Server name; database=BlazorCRUD;Trusted_Connection=True;"
}
}
EmployeeService.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
namespace BlazorCRUD.Data
{
public class EmployeeService
{
#region Property
private readonly AppDBContext_appDBContext;
#endregion
#region Constructor
public EmployeeService(AppDBContextappDBContext)
{
_appDBContext=appDBContext;
}
#endregion
#region Get List of Employees
public async Task<List<Employee>> GetAllEmployeesAsync()
{
return await _appDBContext.Employees.ToListAsync();
}
#endregion
#region Insert Employee
public async Task<bool> InsertEmployeeAsync(Employeeemployee)
{
await _appDBContext.Employees.AddAsync(employee);
await _appDBContext.SaveChangesAsync();
return true;
}
#endregion
#region Get Employee by Id
public async Task<Employee> GetEmployeeAsync(int Id)
{
Employee employee = await
_appDBContext.Employees.FirstOrDefaultAsync(c=>c.Id.Equals(Id));
returnemployee;
}
#endregion
#region Update Employee
public async Task<bool> UpdateEmployeeAsync(Employeeemployee)
{
_appDBContext.Employees.Update(employee);
await _appDBContext.SaveChangesAsync();
return true;
}
#endregion
#region DeleteEmployee
public async Task<bool> DeleteEmployeeAsync(Employeeemployee)
{
_appDBContext.Remove(employee);
await _appDBContext.SaveChangesAsync();
return true;
}
#endregion
}
Configure the connection setup and inject the EmployeeService in Configure Services method in a startup.cs file.
Startup.cs
public void ConfigureServices(IServiceCollectionservices)
{
services.AddRazorPages();services.AddServerSideBlazor();
services.AddSingleton<WeatherForecastService>();
services.AddScoped<EmployeeService>();
#regionConnection String
services.AddDbContext<AppDBContext>(item=>item.UseSqlServer(Configuration.GetConnectionString("myconn")));
#endregion
}
Create the table by using these commands in Package Console Manager
Commands
Add-Migration ‘Your Migration Name’ Update-Database
Now the actual binding of Data will see once we create the Razor pages inside the Pages folder lets create pages and for each form. Will create the Employee Form where it will have the data table to show all the Saved information in it.
To create a Razor component Right Click on pages -> Click on Add -> Click on Razor Component then create a page with the Employee.Razor.
Employees.Razor
@page "/Employees"
@usingBlazorCRUD.Data
@inject EmployeeService employeeService
<Nav Link class="nav-link"href="AddEmployee">
<spanclass="oi oi-plus"aria-hidden="true">Add New</span>
</NavLink>
<h1>Employee Info</h1>
@if (EmpObjisnull)
{
<p><em>Loading... !</em></p>
}
else
{
<tableclass="table">
<thead>
<tr>
<th>EmpId</th>
<th>EmployeeName</th>
<th>Gender</th>
<th>Designation</th>
<th>City</th>
<th>Action</th>
</tr>
</thead>
<tbody>
@foreach(varempinEmpObj)
{
<tr>
<td>@emp.Id</td>
<td>@emp.EmployeName</td>
<td>@emp.Gender</td>
<td>@emp.Designation</td>
<td>@emp.City</td>
<td>
<aclass="nav-link"href="EditEmployee/@emp.Id">
<spanclass="oi oi-pencil"aria-hidden="true">
Edit</span>
</a>
<aclass="nav-link"href="Delete/@emp.Id">
<spanclass="oi oi-trash"aria-hidden="true">
Delete</span>
</a>
</td>
</tr>}
</tbody>
</table>
}
@code{
List<Employee> EmpObj;
protected override async TaskOnInitializedAsync()
{
EmpObj = await Task.Run(() =>employeeService.GetAllEmployeesAsync());
}
@page — the actual navigation page name
@inject — Injection of Service layer here to have interaction with Business logic
@code — Where we call the service method to bind all the values inside the Razor component.
AddEmployee.Razor
Injected the NavigateManager to navigate from one page to another with the page names.
@page "/AddEmployee"
@using BlazorCRUD.Data
@inject EmployeeService employeeService
@inject NavigationManager NavigationManager
<h2>Add 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 form="Name" class="form-control"
@bind="@obj.EmployeName" />
</div>
<div class="form-group">
<label for="Gender" class="control-label"></label>
<select @bind="@obj.Gender" class="form-control">
<option value="">-Select Gender</option>
<option value="Male">Male</option>
<option value="Female">Female</option>
</select>
</div>
<div class="form-group">
<label for="Designation" class="control-
label">Designation</label>
<input form="Designation" class="form-control"
@bind="@obj.Designation" />
</div>
<div class="form-group">
<label for="City" class="control-label">City</label>
<input form="City" class="form-control" @bind="@obj.City" />
</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 btn-primary"
@onclick="@Cancel" value="Cancel"/>
</div>
</div>
</div>
</form>
@code {
Employee obj = new Employee();
protected async void CreateEmployee()
{
await employeeService.InsertEmployeeAsync(obj);
NavigationManager.NavigateTo("Employees");
}
void Cancel()
{
NavigationManager.NavigateTo("Employees");
}
}
EditEmployee.razor
@page "/EditEmployee/{Id}"
@usingBlazorCRUD.Data
@inject EmployeeService employeeService
@inject NavigationManager NavigationManager
<h2>Edit Employee</h2>
<hr />
<form>
<divclass="row">
<divclass="col-md-8">
<divclass="form-group">
<inputform="Name"class="form-control"@bind="@obj.Id" />
</div>
<divclass="form-group">
<labelfor="Name"class="control-label">Name</label>
<inputform="Name"class="form-
control"@bind="@obj.EmployeName" />
</div>
<divclass="form-group">
<labelfor="Gender"class="control-label"></label>
<select@bind="@obj.Gender"class="form-control">
<optionvalue="">-Select Gender</option>
<optionvalue="Male">Male</option>
<optionvalue="Female">Female</option>
</select>
</div>
<divclass="form-group">
<labelfor="Designation"class="control-
label">Designation</label>
<inputform="Designation"class="form-
control"@bind="@obj.Designation" />
</div>
<divclass="form-group">
<labelfor="City"class="control-label">City</label>
<inputform="City"class="form-control"@bind="@obj.City" />
</div>
</div>
</div>
<divclass="row">
<divclass="col-md-4">
<divclass="form-group">
<inputtype="button"class="btn btn-
primary"@onclick="@UpdateEmployee"value="Update" />
<inputtype="button"class="btn btn-
primary"@onclick="@Cancel"value="Cancel" />
</div>
</div>
</div>
</form>
@code{
[Parameter]
public stringId{get; set; }
Employeeobj = new Employee();
protected override async TaskOnInitializedAsync()
{
obj = await Task.Run(() =>employeeService.GetEmployeeAsync(Convert.ToInt32(Id)));
}
protected async voidUpdateEmployee()
{
await employeeService.UpdateEmployeeAsync(obj);
NavigationManager.NavigateTo("Employees");
}
void Cancel()
{
NavigationManager.NavigateTo("Employees");
}
}
Actually, we used to pass the Id for Edit employee to fetch the details from the database and to store them in the edit employee form.
Delete.Razor
@page "/Delete/{Id}"
@using BlazorCRUD.Data
@inject EmployeeService employeeService
@inject NavigationManager NavigationManager
<h2>Delete Employee</h2>
<hr />
<h3>Are you sure want to delete this?</h3>
<form>
<divclass="row">
<divclass=" col-md-8">
<divclass="form-group">
<label>Employee Id:</label>
<label>@obj.Id</label>
</div>
<divclass="form-group">
<label>Employee Name:</label>
<label>@obj.EmployeName</label>
</div>
<divclass="form-group">
<label>Desigation:</label>
<label>@obj.Designation</label>
</div>
<divclass="form-group">
<label>Gender:</label>
<label>@obj.Gender</label>
</div>
<divclass="form-group">
<label>City:</label>
<label>@obj.City</label>
</div>
</div>
</div>
<divclass="row">
<divclass="col-md-4">
<divclass="form-group">
<inputtype="button"class="btn btn-danger"
@onclick="@DeleteEmployee"value="Delete" />
<inputtype="button"class="btn btn-primary"
@onclick="@Cancel"value="Cancel" />
</div>
</div>
</div>
</form>
@code{
[Parameter]
public stringId{get; set; }
Employeeobj = new Employee();
protected override asyncTaskOnInitializedAsync()
{
obj = await Task.Run(() =>employeeService.GetEmployeeAsync(Convert.ToInt32(Id)));
}
protected async void DeleteEmployee()
{
await employeeService.DeleteEmployeeAsync(obj);
NavigationManager.NavigateTo("Employees");
}
void Cancel()
{
NavigationManager.NavigateTo("Employees");
}
}
Run and test the application
Click on the employee tab you will see all the existing details in the grid
Blazor Crud
Thanks for staying till the end and also Thank you for reading, please let me know your questions, thoughts, or feedback in the comments section. I appreciate your feedback and encouragement.
Source: Medium - Jay Krishna Reddy
The Tech Platform
Comments