Tutorial - Employee Management System - Part 1

Employee Management System - Part 1: Displaying a Static Employee List in Blazor Server

EMS: Displaying a Static Employee List in Blazor Server

This guide will walk you through setting up a Blazor Server application to display a static list of employees, preparing the foundation for future integration with a REST API.

Project Structure Overview:

  • EmployeeManagement.Models: A .NET Standard Class Library project that will contain our data model classes (Employee, Department, Gender). This project can be shared across different layers (e.g., API, Web).
  • EmployeeManagement.Web: A Blazor Server project that will serve as our web application, responsible for displaying and interacting with employee data.

Step-by-Step Tutorial Guide

Part 1: Create the Model Project (EmployeeManagement.Models)

  1. Open Visual Studio: Launch Visual Studio 2022 (or a compatible version).
  2. Create a New Project:
    • Click "Create a new project".
    • Search for "Class Library" and select "Class Library (.NET Standard)". Click "Next".
    • Project name: EmployeeManagement.Models
    • Location: Choose a suitable directory for your solution.
    • Solution name: BlazorTutorial (or any name you prefer for your solution).
    • Click "Next".
    • Framework: .NET Core 6.0 or + (or a compatible version).
    • Click "Create".
  3. Define Model Classes:
    • In the EmployeeManagement.Models project, delete the default Class1.cs file.
    • Right-click on the EmployeeManagement.Models project in Solution Explorer, select "Add" -> "Class...".
    • Add the following three classes (create each one separately):
      • Employee.cs
      • Gender.cs
      • Department.cs
  4. Employee.cs:
  5. using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace EmployeeManagement.Models
    {
        public class Employee
        {
            public int EmployeeId { get; set; }
            public string FirstName { get; set; }
            public string LastName { get; set; }
            public string Email { get; set; }
            public DateTime DateOfBrith { get; set; }
            public Gender Gender { get; set; }
            public Department Department { get; set; } // Note: This will be null in our current static data setup
            public string PhotoPath { get; set; }
        }
    }
    
  6. Gender.cs:
  7. namespace EmployeeManagement.Models
    {
        public enum Gender
        {
            Male,
            Female,
            Other
        }
    }
    
  8. Department.cs:
  9. namespace EmployeeManagement.Models
    {
        public class Department
        {
            public int DepartmentId { get; set; }
            public string DepartmentName { get; set; }
        }
    }
    
  10. Build the project: Right-click on EmployeeManagement.Models and select "Build". Ensure there are no errors.

Part 2: Create the Blazor Web Project (EmployeeManagement.Web)

  1. Add a New Project to the Solution:
    • Right-click on your BlazorTutorial solution in Solution Explorer, select "Add" -> "New Project...".
    • Search for "Blazor Server App" and select it. Click "Next".
    • Project name: EmployeeManagement.Web
    • Location: Ensure it's in the same solution directory.
    • Click "Next".
    • Framework: .NET 8.0 (Long Term Support) (or the latest stable LTS version).
    • Authentication type: "None".
    • Click "Create".
  2. Add Project Reference:
    • In the EmployeeManagement.Web project, right-click on "Dependencies", select "Add Project Reference...".
    • In the "Reference Manager" dialog, go to "Projects" -> "Solution".
    • Check the box next to EmployeeManagement.Models.
    • Click "OK".
  3. Set as Startup Project:
    • Right-click on the EmployeeManagement.Web project in Solution Explorer.
    • Select "Set as Startup Project".

Part 3: Configure the Web Project (EmployeeManagement.Web)

Now, let's make the necessary changes to the Program.cs file and delete some default Blazor files.

  1. Delete Unnecessary Files and Folders:
    • In your EmployeeManagement.Web project, right-click and "Delete" the following files and folders:
      • Data folder: (This folder contains WeatherForecast.cs and WeatherForecastService.cs, which we won't be using).
      • Pages/Counter.razor
      • Pages/FetchData.razor
      • Pages/Index.razor (We will recreate our own Index.razor later, inheriting from EmployeeListBase.cs)
      • Shared/SurveyPrompt.razor
  2. Modify Program.cs:
    • Open the Program.cs file in your EmployeeManagement.Web project.
    • Remove the using statement:
  3. // Remove this line if it exists (it likely will if you started with a default template)
    // using EmployeeManagement.Web.Data;
    
    • Remove the service registration for WeatherForecastService:
    • Find and remove the line:
    // Remove this line
    // builder.Services.AddSingleton<WeatherForecastService>();
    
    • Your Program.cs should now look something like this (exact comments/structure might vary slightly based on template version, but the key removals are what's important):
    var builder = WebApplication.CreateBuilder(args);
    
    // Add services to the container.
    builder.Services.AddRazorPages();
    builder.Services.AddServerSideBlazor();
    // The line for WeatherForecastService should be removed from here.
    
    var app = builder.Build();
    
    // Configure the HTTP request pipeline.
    if (!app.Environment.IsDevelopment())
    {
        app.UseExceptionHandler("/Error");
        // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
        app.UseHsts();
    }
    
    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseRouting();
    
    app.MapBlazorHub();
    app.MapFallbackToPage("/_Host");
    
    app.Run();
    

Part 4: Create the Employee List Component

We'll create two files for our EmployeeList component: the .razor file for the UI and the .cs file for the C# logic (code-behind).

  1. Add EmployeeList.razor:
    • In the EmployeeManagement.Web project, right-click on the Pages folder, select "Add" -> "Razor Component...".
    • Name it EmployeeList.razor.
    • Replace its content with the following:
  2. @page "/"
    @inherits EmployeeListBase
    
    <h3>Employee List</h3>
    
    @if (Employees == null)
    {
        <div class="spinner"></div>
    }
    @else
    {
        <div class="card-deck">
            @foreach (var employee in Employees)
            {
                <div class="card m-3" style="min-width: 18rem; max-width:30.5%;">
                    <div class="card-header">
                        <h3>@employee.FirstName @employee.LastName</h3>
                    </div>
                    <img class="card-img-top imageThumbnail" src="@employee.PhotoPath" />
                    <div class="card-footer text-center">
                        <a href="#" class="btn btn-primary m-1">View</a>
                        <a href="#" class="btn btn-primary m-1">Edit</a>
                        <a href="#" class="btn btn-danger m-1">Delete</a>
                    </div>
                </div>
            }
        </div>
    }
    
    • Explanation:
      • @page "/": This makes EmployeeList.razor the default component rendered when the application loads at the root URL.
      • @inherits EmployeeListBase: This links the UI component to its C# code-behind class, EmployeeListBase.
      • The @if (Employees == null) block handles the loading state, displaying a spinner until the employee data is loaded.
      • The @foreach loop iterates through the Employees collection (which will be provided by EmployeeListBase) to display each employee as a Bootstrap card.
  3. Add EmployeeListBase.cs (Code-Behind):
    • In the EmployeeManagement.Web project, right-click on the Pages folder, select "Add" -> "Class...".
    • Name it EmployeeListBase.cs.
    • Replace its content with the following:
  4. using EmployeeManagement.Models;
    using Microsoft.AspNetCore.Components;
    using System;
    using System.Collections.Generic;
    using System.Threading.Tasks;
    
    namespace EmployeeManagement.Web.Pages
    {
        public class EmployeeListBase : ComponentBase
        {
            public IEnumerable<Employee> Employees { get; set; }
    
            protected override async Task OnInitializedAsync()
            {
                // Simulate an asynchronous operation (like fetching data from an API)
                await Task.Run(LoadEmployees);
            }
    
            private void LoadEmployees()
            {
                // Simulate network latency
                System.Threading.Thread.Sleep(2000);
    
                // Hardcoded Employee Data
                Employee e1 = new Employee
                {
                    EmployeeId = 1,
                    FirstName = "Raushan",
                    LastName = "Ranjan",
                    Email = "Raushan@rrtech.com",
                    DateOfBrith = new DateTime(1998, 11, 11),
                    Gender = Gender.Male,
                    // Department = new Department { DepartmentId = 1, DepartmentName = "IT" }, // Commented out as Department isn't fully set up in static data
                    PhotoPath = "images/raushan.jpg"
                };
    
                Employee e2 = new Employee
                {
                    EmployeeId = 2,
                    FirstName = "Sam",
                    LastName = "Galloway",
                    Email = "Sam@rrtech.com",
                    DateOfBrith = new DateTime(1981, 12, 22),
                    Gender = Gender.Male,
                    // Department = new Department { DepartmentId = 2, DepartmentName = "HR" },
                    PhotoPath = "images/john.png"
                };
    
                Employee e3 = new Employee
                {
                    EmployeeId = 3,
                    FirstName = "Pratibha",
                    LastName = "Poddar",
                    Email = "pratibha@rrtech.com",
                    DateOfBrith = new DateTime(2000, 07, 11),
                    Gender = Gender.Female,
                    // Department = new Department { DepartmentId = 1, DepartmentName = "IT" },
                    PhotoPath = "images/pratibha.png"
                };
    
                Employee e4 = new Employee
                {
                    EmployeeId = 4, // Corrected EmployeeId for uniqueness
                    FirstName = "Sara",
                    LastName = "Longway",
                    Email = "sara@rrtech.com",
                    DateOfBrith = new DateTime(1982, 9, 23),
                    Gender = Gender.Female,
                    // Department = new Department { DepartmentId = 3, DepartmentName = "Payroll" },
                    PhotoPath = "images/mary.png"
                };
    
                Employees = new List<Employee> { e1, e3, e2, e4 }; // You can arrange the order as you like
            }
        }
    }
    
    • Explanation:
      • @inherits ComponentBase: This class inherits from Blazor's ComponentBase, providing lifecycle methods.
      • Employees { get; set; }: This property will hold the list of employees that the EmployeeList.razor UI binds to.
      • protected override async Task OnInitializedAsync(): This lifecycle method is called when the component is initialized. We use async/await and Task.Run() to simulate an asynchronous data loading operation, which is typical when fetching data from a server.
      • LoadEmployees(): This private method currently contains our hardcoded employee data. The Thread.Sleep(2000) simulates a 2-second delay to show the loading spinner.

Part 5: Update Layout and Styling

  1. Modify Shared/MainLayout.razor:
    • Open Shared/MainLayout.razor.
    • Locate the div element that wraps @Body.
    • Add the Bootstrap container class to it.
  2. Before:
  3. <div class="main">
        <div class="content px-4">
            @Body
        </div>
    </div>
    
  4. After:
  5. <div class="main">
        <div class="content px-4 container">
            @Body
        </div>
    </div>
    
  6. Add CSS to wwwroot/css/site.css:
    • Open wwwroot/css/site.css.
    • Add the following CSS rules for image styling and the loading spinner:
  7. .imageThumbnail {
        height: 200px;
        width: auto;
    }
    .spinner {
        border: 16px solid silver;
        border-top: 16px solid #337AB7; /* Bootstrap primary blue */
        border-radius: 50%;
        width: 80px;
        height: 80px;
        animation: spin 700ms linear infinite;
        top: 40%;
        left: 55%;
        position: absolute;
        z-index: 1000; /* Ensure it's above other content */
    }
    
    @keyframes spin {
        0% {
            transform: rotate(0deg);
        }
        100% {
            transform: rotate(360deg);
        }
    }
    

Part 6: Add Images

  1. Download Images:
    • Download the four employee images (e.g., raushan.jpg, john.png, pratibha.png, mary.png). You can use placeholder images if you don't have these specific ones. Make sure their filenames match what's used in EmployeeListBase.cs.
  2. Place Images in wwwroot/images:
    • In your EmployeeManagement.Web project, expand the wwwroot folder.
    • If an images folder doesn't exist, right-click on wwwroot, select "Add" -> "New Folder", and name it images.
    • Drag and drop (or copy and paste) your downloaded images into the wwwroot/images folder.

Part 7: Run the Application

  1. Build the Solution:
    • Go to "Build" -> "Build Solution" (or press Ctrl+Shift+B).
    • Ensure there are no build errors.
  2. Run the Application:
    • Press F5 or click the "Run" button (green play icon) in Visual Studio.
    • You should now see your Blazor application launch in a web browser. Initially, you'll see a loading spinner for about 2 seconds, and then the list of employees will appear, styled with Bootstrap cards and their respective images.

Comments

Popular posts from this blog

Blazor: Building Web Apps with C# - Introduction

Blazor WebAssembly Hosted App Tutorial: Envelope Tracker System

Securing MVC-based Applications Using Blazor