Lesson 10 of 10

Mini Project: Build a Student Manager

Combine components, forms, DI, and collections to build a practical in-memory Student Manager application.

Visual Studio 2026.NET 10Beginner friendly

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

  1. Run the application.
  2. Open /student-manager.
  3. Try submitting an empty form and confirm validation appears.
  4. Add two students.
  5. Delete one student.
  6. 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.