A Deep Dive into C# Text Connection
In Lesson 11 of Tim Corey’s “C# App Start to Finish” series, Tim explains how to save data into text files using a text-based data connection. Tim begins by reminding viewers that, in the previous lesson, they set up the SQL connection and performed key housekeeping tasks. Now, the focus shifts to the Text Connection, and the goal is clear: make the text connection work just like the SQL connection, where the system can take a PrizeModel and return it with its ID properly filled out. Tim emphasizes that the video will show a complete workflow for storing, reading, and updating data using plain text files.
The Solution — Setting Up Text Connection
Tim starts by opening the Text Connector inside the DataAccess folder. He deletes the sample code and begins from scratch. He explains that unlike SQL, text files don’t provide smart database features like auto-incrementing IDs. So the first task is deciding where to store the text files.
Tim proposes a clean design: store each model in its own text file. For example, PrizeModel will have its own file called PrizeModels.csv, while other models like MatchupModel will each have separate files. Tim compares this structure to SQL tables — each file becomes a “table” containing a list of that model. This makes data easy to manage and prevents mixing different model types together.
The Connection String — Storing File Path
Tim explains that instead of storing a single file name, you store a path to the folder where all files will be saved. This path is placed in the app.config under appSettings. Tim adds a new key-value pair:
Key: filePath
- Value: the folder path where the files will be stored
He emphasizes using the correct Windows syntax and avoids ending the path with a slash, since he prefers adding the slash only when building the full file path. This setup is crucial because it makes the application flexible—if the storage location changes, you only update the app.config.
The Plan — How Text Connection Works
Tim outlines a clear plan for saving a prize:
Load the text file containing all prizes.
Convert text lines to a list of PrizeModel.
Find the highest ID in the list and set new ID = highest ID + 1.
Add the new prize model to the list.
Convert the list of prizes back into text lines.
- Save the list back to the text file, overwriting the old data.
Tim explains that text files are “stupid” compared to SQL databases. SQL can manage IDs automatically, but text files require the developer to implement logic manually. This is why Tim breaks the process into smaller methods to keep the code clean and reusable.
Creating a New Class — Text Connector Processor
Tim creates a new class called TextConnectorProcessor. He places it inside the DataAccess folder but in a different namespace to avoid cluttering the main namespace. Tim explains that namespaces are flexible and can be customized, but he recommends keeping them simple and clean.
He makes the class public static and starts building helper methods.
Extension Method — Full File Path
Tim creates an extension method:
public static string FullFilePath(this string fileName)This method combines the filePath from app.config with the file name to generate the full file path. Tim demonstrates how to use ConfigurationManager.AppSettings["filePath"] and explains the necessity of escaping slashes in C# strings (using \\).
He then converts the method into an extension method so it can be used like this:
"PrizeModels.csv".FullFilePath()Tim explains that this extension method is only needed in the text connector, so he keeps it in a separate namespace to avoid showing it everywhere in the solution.
Load File Method — Reading Text Data
Next, Tim creates another extension method:
public static List<string> LoadFile(this string file)This method checks if the file exists using File.Exists(). If the file doesn’t exist, it returns an empty list. If it does exist, it reads all lines using File.ReadAllLines() and converts them into a list.
Tim highlights the importance of handling missing files properly since this is common in the first run of the application.
Convert Text to Prize Models
Tim creates a method to convert the loaded text lines into a list of PrizeModel:
public static List<PrizeModel> ConvertToPrizeModels(this List<string> lines)He explains the use of comma-separated values (CSV) where each line contains fields separated by commas. Tim splits each line into columns and parses them into the appropriate data types:
ID → int.Parse()
PlaceNumber → int.Parse()
PlaceName → string
PrizeAmount → decimal.Parse()
- PrizePercentage → double.Parse()
Tim also explains that he intentionally allows the application to crash if the data is invalid. This helps reveal problems early instead of continuing with corrupted data.
Finding the Max ID
Tim returns to the TextConnector and explains how to find the highest ID:
int currentID = prizes.OrderByDescending(x => x.ID).First().ID + 1;He notes this will crash if the file is empty, so he adds a check:
if(prizes.Count > 0)
{
currentID = prizes.OrderByDescending(x => x.ID).First().ID + 1;
}This ensures the first record gets an ID of 1.
Adding Model and Saving
Tim adds the new prize to the list and then converts the list back into text lines:
public static void SaveToPrizeFile(this List<PrizeModel> models, string fileName)He uses string interpolation to create each CSV line and adds it to a list of strings. Finally, he uses:
File.WriteAllLines(fileName.FullFilePath(), lines);Tim explains that WriteAllLines overwrites the file, which is desired behavior because it refreshes the data with updated content.
Returning the Model
Tim concludes the method by returning the PrizeModel with the assigned ID. This makes the new prize usable in the rest of the application, just like SQL.
Testing the Text Connection
Tim switches to Program.cs and changes the data connection from SQL to Text. When he runs the application and creates prizes, the system initially crashes due to missing records. Tim quickly fixes the bug with the if(prizes.Count > 0) check, then runs again.
He demonstrates that the data is correctly saved into the PrizeModels.csv file and shows how the file can be opened in Notepad or Excel.
Final Thoughts — Extension Methods and Namespaces
Tim ends the lesson by reminding viewers that the extension methods only appear when the correct namespace is included. This avoids clutter and potential naming conflicts. He notes that these two lessons create a strong foundation for the rest of the application and sets the stage for future development.

