Sign in to track progress and bookmarks.
Welcome to the pinnacle of the ASP.NET Core MVC Mastery course. Everything you've learned—Dependency Injection, Entity Framework Core, Repositories, ViewModels, Validations, and Security—will now seamlessly converge into a fully functional, production-ready Employee Management System. This isn't just theory; this is the exact architecture you will build in enterprise environments.
We will construct an N-Tier monolithic application respecting Clean Architecture boundaries. This ensures testability and separation of concerns.
IEmployeeRepository.public class Employee
{
public int Id { get; set; }
public string FullName { get; set; }
public string Email { get; set; }
public DateTime DateOfJoining { get; set; }
public decimal Salary { get; set; }
// Establishing a 1-to-Many Relationship
public int DepartmentId { get; set; }
public Department Department { get; set; }
}
// The contract the database implementation must fulfill
public interface IEmployeeRepository
{
Task<IEnumerable<Employee>> GetAllEmployeesAsync();
Task<Employee> GetEmployeeByIdAsync(int id);
Task AddEmployeeAsync(Employee employee);
Task UpdateEmployeeAsync(Employee employee);
Task DeleteEmployeeAsync(int id);
}
For operations like Creating an employee, we explicitly dictate required fields using ViewModels and FluentValidation.
public class EmployeeCreateViewModel
{
[Required(ErrorMessage = "Please provide a name")]
[StringLength(100, MinimumLength = 2)]
public string FullName { get; set; }
[Required]
[EmailAddress]
// Utilizes AJAX to check the DB without refreshing the page
[Remote(action: "IsEmailAvailable", controller: "Validation")]
public string Email { get; set; }
[Required]
[Range(30000, 200000, ErrorMessage = "Salary must be realistic.")]
public decimal Salary { get; set; }
[Display(Name = "Department")]
public int DepartmentId { get; set; }
}
Controllers should focus entirely on HTTP logic (handling requests, validating model state, and returning UI views/redirects). They should delegate database operations to Repositories to enable Unit Testing.
[Authorize] // Secure the entire route
public class EmployeeController : Controller
{
private readonly IEmployeeRepository _repo;
// Dependency Injection guarantees testing mocks can be swapped here
public EmployeeController(IEmployeeRepository repo)
=> _repo = repo;
[HttpGet]
public async Task<IActionResult> Create()
{
// Load dropdown lists (SelectLists) for UI forms
ViewBag.Departments = await _repo.GetDepartmentsAsync();
return View(new EmployeeCreateViewModel());
}
[HttpPost]
[ValidateAntiForgeryToken] // CSRF Protection enforced globally
public async Task<IActionResult> Create(EmployeeCreateViewModel model)
{
// 1. Immediately validate inputs
if (!ModelState.IsValid)
{
ViewBag.Departments = await _repo.GetDepartmentsAsync();
return View(model); // Bounce back with error states
}
// 2. Map ViewModel -> Domain Model
var entity = new Employee
{
FullName = model.FullName,
Email = model.Email,
Salary = model.Salary,
DepartmentId = model.DepartmentId,
DateOfJoining = DateTime.UtcNow
};
// 3. Delegate to Repository
await _repo.AddEmployeeAsync(entity);
// 4. Implement PRG Pattern using TempData
TempData["SuccessMessage"] = $"Employee {entity.FullName} onboarded securely.";
return RedirectToAction(nameof(Index));
}
}
Quizzes linked to this course—pass to earn certificates.
On this page
1. Project Architecture Blueprint 2. Defining the Domain & Repository 3. DTOs and Validation 4. The Thin Controller Methodology 5. Final Capstone Checklist