ASP.NET Core  

Human Resource Management System in ASP.NET Core MVC

Introduction

Human Resource Management Systems (HRMS) are essential for modern organizations. They automate employee records, payroll, attendance, and recruitment. The open‑source HRM project demonstrates how to build a complete HRMS using ASP.NET Core MVC, Entity Framework Core, and SQL Server.

Step 1: Environment Setup

  • Install Visual Studio 2022 with ASP.NET workload.

  • Install SQL Server and SSMS.

  • Clone the repository:

    bash

    git clone https://github.com/brajeshkr18/HRM.git
    
  • Open the solution in Visual Studio.

Step 2: Database Configuration

  • Update appsettings.json with your SQL Server connection string.

  • Run EF Core migrations:

    bash

    Update-Database
    
  • This creates tables like AspNetUsers, AspNetRoles, Companies, Departments, Designations.

Step 3: Authentication & Roles

  • The project uses ASP.NET Identity.

  • Roles: Admin, HR, Manager, Employee.

  • Login page: /Identity/Account/Login.

  • Debugging tip: Place a breakpoint in Login.cshtml.cs → OnPostAsync() to inspect validation.

Step 4: Admin Module

  • Dashboard → Overview of employees, departments, payroll.

  • Companies → CRUD for company records.

  • Departments → CRUD linked to companies.

  • Designations → CRUD linked to companies.

  • Role Management → Assign roles to users.

Step 5: HR Module

  • Employee Management → Add, edit, delete employees.

  • Attendance → Mark daily attendance.

  • Leave Requests → Approve/reject employee leave.

  • Recruitment → Generate offer letters, onboarding workflows.

Step 6: Manager Module

  • Team Dashboard → View team members and performance.

  • Approve Leave → Approve/reject leave requests.

  • Reports → Attendance and performance reports.

Step 7: Employee Module

  • Profile → View/update personal details.

  • Attendance → Mark attendance.

  • Leave Application → Submit leave requests.

  • Salary Slip → View/download salary slips.

  • Offer Letter → View recruitment documents.

Step 8: Payroll & Reports

  • Payroll Management → Salary calculation, deductions, bonuses.

  • Salary Slips → Generate and export slips.

  • Reports → Attendance, payroll, performance analytics.

Step 9: Deployment

  • Publish to IIS or Azure.

  • Configure connection strings for production.

  • Secure sensitive data with Azure Key Vault or environment variables.

🏢 Admin Module – Companies, Departments, Designations

Companies Page

Step 1: Model

csharp

public class Company
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int LocId { get; set; }
    public string Address { get; set; }

    public Location Location { get; set; }
    public ICollection<Department> Departments { get; set; }
}

Step 2: Controller

csharp

public class CompaniesController : Controller
{
    private readonly ApplicationDbContext _context;
    public CompaniesController(ApplicationDbContext context) => _context = context;

    public async Task<IActionResult> Index()
    {
        var companies = await _context.Companies.Include(c => c.Location).ToListAsync();
        return View(companies);
    }

    public IActionResult Create() => View();

    [HttpPost]
    public async Task<IActionResult> Create(Company company)
    {
        if (ModelState.IsValid)
        {
            _context.Add(company);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(company);
    }
}

Step 3: View

html

@model IEnumerable<Company>

<h2>Companies</h2>
<table class="table">
    <tr><th>Name</th><th>Location</th><th>Address</th></tr>
    @foreach (var c in Model)
    {
        <tr>
            <td>@c.Name</td>
            <td>@c.Location.Name</td>
            <td>@c.Address</td>
        </tr>
    }
</table>

📸 Screenshot

company

Departments Page

Step 1: Model

csharp

public class Department
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int CompanyId { get; set; }

    public Company Company { get; set; }
}

Step 2: Controller

csharp

public class DepartmentsController : Controller
{
    private readonly ApplicationDbContext _context;
    public DepartmentsController(ApplicationDbContext context) => _context = context;

    public async Task<IActionResult> Index()
    {
        var departments = await _context.Departments.Include(d => d.Company).ToListAsync();
        return View(departments);
    }

    public IActionResult Create() => View();

    [HttpPost]
    public async Task<IActionResult> Create(Department department)
    {
        if (ModelState.IsValid)
        {
            _context.Add(department);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(department);
    }
}

Step 3: View

html

@model IEnumerable<Department>

<h2>Departments</h2>
<table class="table">
    <tr><th>Name</th><th>Company</th></tr>
    @foreach (var d in Model)
    {
        <tr>
            <td>@d.Name</td>
            <td>@d.Company.Name</td>
        </tr>
    }
</table>

📸 Screenshot

company

Designations Page

Step 1: Model

csharp

public class Designation
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int CompanyId { get; set; }

    public Company Company { get; set; }
}

Step 2: Controller

csharp

public class DesignationsController : Controller
{
    private readonly ApplicationDbContext _context;
    public DesignationsController(ApplicationDbContext context) => _context = context;

    public async Task<IActionResult> Index()
    {
        var designations = await _context.Designations.Include(d => d.Company).ToListAsync();
        return View(designations);
    }

    public IActionResult Create() => View();

    [HttpPost]
    public async Task<IActionResult> Create(Designation designation)
    {
        if (ModelState.IsValid)
        {
            _context.Add(designation);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(designation);
    }
}

Step 3: View

html

@model IEnumerable<Designation>

<h2>Designations</h2>
<table class="table">
    <tr><th>Name</th><th>Company</th></tr>
    @foreach (var d in Model)
    {
        <tr>
            <td>@d.Name</td>
            <td>@d.Company.Name</td>
        </tr>
    }
</table>

📸 Screenshot

company

👩‍💼 HR Module – Employee Management

Employee Model

Define the employee entity with relationships to company, department, and designation:

csharp

public class Employee
{
    public int Id { get; set; }
    public string FullName { get; set; }
    public string Email { get; set; }
    public string Phone { get; set; }

    public int CompanyId { get; set; }
    public Company Company { get; set; }

    public int DepartmentId { get; set; }
    public Department Department { get; set; }

    public int DesignationId { get; set; }
    public Designation Designation { get; set; }

    public DateTime JoiningDate { get; set; }
}

Employee Controller

Create an MVC controller to handle CRUD operations:

csharp

public class EmployeesController : Controller
{
    private readonly ApplicationDbContext _context;
    public EmployeesController(ApplicationDbContext context) => _context = context;

    // List all employees
    public async Task<IActionResult> Index()
    {
        var employees = await _context.Employees
            .Include(e => e.Company)
            .Include(e => e.Department)
            .Include(e => e.Designation)
            .ToListAsync();
        return View(employees);
    }

    // Create employee
    public IActionResult Create()
    {
        ViewBag.Companies = new SelectList(_context.Companies, "Id", "Name");
        ViewBag.Departments = new SelectList(_context.Departments, "Id", "Name");
        ViewBag.Designations = new SelectList(_context.Designations, "Id", "Name");
        return View();
    }

    [HttpPost]
    public async Task<IActionResult> Create(Employee employee)
    {
        if (ModelState.IsValid)
        {
            _context.Add(employee);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(employee);
    }

    // Edit employee
    public async Task<IActionResult> Edit(int id)
    {
        var employee = await _context.Employees.FindAsync(id);
        if (employee == null) return NotFound();

        ViewBag.Companies = new SelectList(_context.Companies, "Id", "Name", employee.CompanyId);
        ViewBag.Departments = new SelectList(_context.Departments, "Id", "Name", employee.DepartmentId);
        ViewBag.Designations = new SelectList(_context.Designations, "Id", "Name", employee.DesignationId);

        return View(employee);
    }

    [HttpPost]
    public async Task<IActionResult> Edit(Employee employee)
    {
        if (ModelState.IsValid)
        {
            _context.Update(employee);
            await _context.SaveChangesAsync();
            return RedirectToAction(nameof(Index));
        }
        return View(employee);
    }

    // Delete employee
    public async Task<IActionResult> Delete(int id)
    {
        var employee = await _context.Employees.FindAsync(id);
        if (employee == null) return NotFound();

        _context.Employees.Remove(employee);
        await _context.SaveChangesAsync();
        return RedirectToAction(nameof(Index));
    }
}

Employee Views

Index.cshtml

html

@model IEnumerable<Employee>

<h2>Employees</h2>
<a asp-action="Create" class="btn btn-primary">Add Employee</a>

<table class="table">
    <tr>
        <th>Name</th><th>Email</th><th>Phone</th>
        <th>Company</th><th>Department</th><th>Designation</th><th>Joining Date</th><th>Actions</th>
    </tr>
    @foreach (var e in Model)
    {
        <tr>
            <td>@e.FullName</td>
            <td>@e.Email</td>
            <td>@e.Phone</td>
            <td>@e.Company.Name</td>
            <td>@e.Department.Name</td>
            <td>@e.Designation.Name</td>
            <td>@e.JoiningDate.ToShortDateString()</td>
            <td>
                <a asp-action="Edit" asp-route-id="@e.Id">Edit</a> |
                <a asp-action="Delete" asp-route-id="@e.Id">Delete</a>
            </td>
        </tr>
    }
</table>

Create.cshtml

html

@model Employee

<h2>Add Employee</h2>
<form asp-action="Create">
    <div class="form-group">
        <label>Name</label>
        <input asp-for="FullName" class="form-control" />
    </div>
    <div class="form-group">
        <label>Email</label>
        <input asp-for="Email" class="form-control" />
    </div>
    <div class="form-group">
        <label>Phone</label>
        <input asp-for="Phone" class="form-control" />
    </div>
    <div class="form-group">
        <label>Company</label>
        <select asp-for="CompanyId" asp-items="ViewBag.Companies" class="form-control"></select>
    </div>
    <div class="form-group">
        <label>Department</label>
        <select asp-for="DepartmentId" asp-items="ViewBag.Departments" class="form-control"></select>
    </div>
    <div class="form-group">
        <label>Designation</label>
        <select asp-for="DesignationId" asp-items="ViewBag.Designations" class="form-control"></select>
    </div>
    <div class="form-group">
        <label>Joining Date</label>
        <input asp-for="JoiningDate" type="date" class="form-control" />
    </div>
    <button type="submit" class="btn btn-success">Save</button>
</form>

📸 Screenshot

company

Summary

In this article, we walked through the foundation of the HRM project built in ASP.NET Core MVC. Starting from environment setup and database configuration, we explored how authentication and role management work with ASP.NET Identity.

We then focused on the Admin module — covering Companies, Departments, and Designations — and demonstrated how to structure models, controllers, and views for CRUD operations.

Finally, we implemented the Employee module up to Attendance, showing how employees can mark presence and how HR/managers can track attendance records.

✅ Key Takeaways

  • HRM project follows a clean MVC pattern: Model → Controller → View.

  • Identity integration ensures secure login and role‑based dashboards.

  • Admin manages master data (companies, departments, designations).

  • Employees can manage profiles, attendance, and leave workflows.

📌 What’s Next

This first article covered setup + Admin + Employee (Attendance).
In the next part, we’ll continue with:

  • Leave Requests (apply, approve, reject)

  • Payroll (salary slips, reports)

  • Recruitment (offer letters, onboarding)

  • Role‑based dashboards for Admin, HR, Manager, and Employee

Part 2 → Leave requests, Payroll, Recruitment.