Skip to Content
Course content

137: Building a Todo List with Persistence

Click on the "Edit" button in the top corner of the screen to edit your slide content.

Where do I actually save my list so it doesn't disappear when I close the app?

When you're building a small tool like a Todo list, the temptation is to jump straight into a database like SQL Server or MongoDB. Honestly? Don't do that yet. You'll spend more time configuring connection strings than writing actual logic. For this kind of project, a flat JSON file on your hard drive is perfect. It's human-readable, meaning you can open it in a text editor to verify your data is actually there, and it's more than fast enough for a few hundred tasks.

In C#, we use the System.IO namespace to talk to the file system. I usually define a private constant for the filename at the top of my class so I'm not hunting through the code to change "todos.json" to "tasks.json" later.

How do I turn my C# objects into a format a file can understand?

C# objects live in your RAM as complex structures; you can't just "dump" a List<TodoItem> into a text file and expect it to make sense. You need serialization. I always recommend System.Text.Json these days—it's built-in, high-performance, and doesn't require third-party NuGet packages for basic use.

public class TodoItem 
{
    public string Task { get; set; }
    public bool IsCompleted { get; set; }
}

// Saving the list to disk
public void SaveTasks(List<TodoItem> tasks) 
{
    string jsonString = JsonSerializer.Serialize(tasks, new JsonSerializerOptions { WriteIndented = true });
    File.WriteAllText("todos.json", jsonString);
}

The WriteIndented = true part is my personal preference. It makes the resulting JSON file look pretty with line breaks and spaces, which is a lifesaver when you're debugging. Without it, the whole list is just one giant, unreadable line of text.

Do I have to reload the file every time I add or check a task?

This is where a lot of people overcomplicate things. You don't want to read from the disk every single time you toggle a checkbox—that's incredibly inefficient. Instead, treat the file as your "long-term storage" and a local List<TodoItem> as your "working memory."

The workflow I use looks like this:

  • On Startup: Check if the file exists. If it does, deserialize the JSON back into a C# list. If not, start with an empty list.
  • During Runtime: All adds, deletes, and toggles happen to the list in memory.
  • On Change: Call your save method to overwrite the file with the current state of the list.

You might worry that overwriting the whole file is wasteful, but for a Todo list, the file size is tiny. It's much simpler to just overwrite the whole thing than to try and surgically edit one line of JSON inside a text file.




📋 Practical Task

Implement a 'Priority' level with JSON persistence

It's time to put this into practice. I want you to expand the Todo list project by adding a Priority property to the TodoItem class. Use an enum for this (with values like Low, Medium, and High).

Your challenge is to ensure that the priority level is correctly saved to and loaded from your JSON file. Additionally, add a check during the loading process: if the todos.json file is missing or corrupted, your program should catch the exception and initialize a fresh, empty list instead of crashing. Test it by adding a "High Priority" task, restarting the app, and verifying the priority is still there.

Rating
0 0

There are no comments for now.

to be the first to leave a comment.