Mini Project: Build a Student Manager
Combine components, forms, DI, and collections to build a practical in-memory Student Manager application.
This mini project combines several ideas from the previous lessons: models, forms, validation, dependency injection, collections, event handling, and conditional rendering. The data remains in memory so you can focus on Blazor fundamentals.
1. Create StudentManagerService.cs
using System.ComponentModel.DataAnnotations;
namespace BlazorTutorialApp.Services;
public class StudentManagerService
{
private readonly List<StudentItem> students = new()
{
new StudentItem { Id = 1, Name = "Alice Tan", Course = "Computer Science" },
new StudentItem { Id = 2, Name = "John Lee", Course = "Software Engineering" }
};
public IReadOnlyList<StudentItem> GetAll() => students;
public void Add(StudentItem student)
{
student.Id = students.Count == 0 ? 1 : students.Max(s => s.Id) + 1;
students.Add(student);
}
public void Delete(int id)
{
var student = students.FirstOrDefault(s => s.Id == id);
if (student is not null)
students.Remove(student);
}
}
public class StudentItem
{
public int Id { get; set; }
[Required]
public string Name { get; set; } = "";
[Required]
public string Course { get; set; } = "";
}
2. Register the service
builder.Services.AddScoped<StudentManagerService>();
3. Create StudentManager.razor
@page "/student-manager"
@using BlazorTutorialApp.Services
@inject StudentManagerService StudentManager
<PageTitle>Student Manager</PageTitle>
<h1>Student Manager</h1>
<EditForm Model="@newStudent" OnValidSubmit="AddStudent">
<DataAnnotationsValidator />
<div class="mb-3">
<label>Name</label>
<InputText class="form-control" @bind-Value="newStudent.Name" />
<ValidationMessage For="@(() => newStudent.Name)" />
</div>
<div class="mb-3">
<label>Course</label>
<InputText class="form-control" @bind-Value="newStudent.Course" />
<ValidationMessage For="@(() => newStudent.Course)" />
</div>
<button class="btn btn-primary" type="submit">Add Student</button>
</EditForm>
<hr />
@if (StudentManager.GetAll().Count == 0)
{
<p>No students found.</p>
}
else
{
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Course</th>
<th></th>
</tr>
</thead>
<tbody>
@foreach (var student in StudentManager.GetAll())
{
<tr>
<td>@student.Id</td>
<td>@student.Name</td>
<td>@student.Course</td>
<td>
<button class="btn btn-sm btn-danger"
@onclick="() => DeleteStudent(student.Id)">
Delete
</button>
</td>
</tr>
}
</tbody>
</table>
}
<p>@message</p>
@code {
private StudentItem newStudent = new();
private string message = "";
private void AddStudent()
{
StudentManager.Add(new StudentItem
{
Name = newStudent.Name,
Course = newStudent.Course
});
message = $"Added {newStudent.Name}.";
newStudent = new StudentItem();
}
private void DeleteStudent(int id)
{
StudentManager.Delete(id);
message = "Student deleted.";
}
}
4. Test the project
- Run the application.
- Open /student-manager.
- Try submitting an empty form and confirm validation appears.
- Add two students.
- Delete one student.
- Refresh the browser and observe the behavior of the in-memory data.
5. Where to go next
You now have the foundation needed for a larger Blazor course. Natural next lessons are Entity Framework Core, SQL Server/SQLite, full CRUD pages, authentication and authorization, file uploads, JavaScript interoperability, state management, error handling, logging, and deployment.
Challenge
Add an Email field to StudentItem, validate it with [EmailAddress], show it in the table, and add a search box that filters students by name.