With the following code I try to append users that get entered in console to a existing csv file. I'm using CSV helper and I read the documentation.
First I load users from the csv file and store them in a list with this code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Globalization;
using System.Linq;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
public class UserList
{
public static List<User> LoadUsersFromCSV()
{
// using (var mem = new MemoryStream())
// using (var writer = new StreamWriter(mem))
using (var reader = new StreamReader("users.csv"))
using (var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture))
{
// csvReader.Configuration.Delimiter = ";";
// csvReader.Configuration.IgnoreBlankLines = true;
csvReader.Configuration.HasHeaderRecord = true;
// csvReader.Configuration.PrepareHeaderForMatch = (string header, int index) => header.ToLower();
// csvReader.Configuration.MissingFieldFound = null;
csvReader.Read();
csvReader.ReadHeader();
// Store all content inside a new List as objetcs
var users = csvReader.GetRecords<User>().ToList();
return users;
// try
// {
// }
// catch (CsvHelper.HeaderValidationException exception)
// {
// Console.WriteLine(exception);
// }
}
}
}
}
New users get entered via this code:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Globalization;
using System.Linq;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
public class RegisterManager
{
public void Register(List<User> users)
{
// Get user input
Console.WriteLine("Enter username:");
string username = Console.ReadLine();
Console.WriteLine("Enter email:");
string email = Console.ReadLine();
Console.WriteLine("Enter password:");
string password = Console.ReadLine();
Console.WriteLine("Enter userrole (typ admin, purchase or sales):");
string userrole = Console.ReadLine();
// Create fresh instance to save input in memory
User user = new User(username, email, password, userrole);
// Adds the user to the excisting list
users.Add(user);
FileOperations fo = new FileOperations();
// Calling the method from FileOperations.cs to write the List here to a CSV file
fo.WriteUsersToCSV(users);
}
}
}
Then the entered users a written to the existing csv file with the method called WriteUsersToCSV:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Globalization;
using System.Linq;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
// Handles CRUD within CSV files and able to save them
public class FileOperations
{
// Appends to CSV file from List
public void WriteUsersToCSV(List<User> users)
{
// Append to the file
using (var stream = File.Open("users.csv", FileMode.Append))
using (var writer = new StreamWriter(stream))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csvWriter.Configuration.HasHeaderRecord = false;
csvWriter.WriteRecords(users);
Console.WriteLine("New user added to users.csv");
}
}
// Writes to CSV file from List
public void WriteUsersToNewCSVFile(List<User> users)
{
using (var writer = new StreamWriter("users.csv"))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
// csvWriter.Configuration.Delimiter = ";";
csvWriter.Configuration.HasHeaderRecord = true;
csvWriter.Configuration.AutoMap<User>();
csvWriter.WriteHeader<User>();
csvWriter.WriteRecords(users);
Console.WriteLine("New file users.csv created!");
}
}
// Reads from CSV file and displays content from it
public void ReadUsersFromCSV()
{
using (var reader = new StreamReader("users.csv"))
using (var csvReader = new CsvReader(reader, CultureInfo.InvariantCulture))
{
try
{
// csvReader.Configuration.Delimiter = ";";
// csvReader.Configuration.IgnoreBlankLines = true;
csvReader.Configuration.HasHeaderRecord = true;
// csvReader.Configuration.PrepareHeaderForMatch = (string header, int index) => header.ToLower();
// csvReader.Configuration.MissingFieldFound = null;
csvReader.Read();
csvReader.ReadHeader();
// Store all content inside a new List as objetcs
var records = csvReader.GetRecords<User>().ToList();
// Loop through the List and show them in Console (connect to values in the constructor User.cs record.username etc..)
foreach (var record in records)
{
Console.WriteLine($"{record.username } | {record.email} | {record.password} | {record.userrole}");
}
}
catch (CsvHelper.HeaderValidationException exception)
{
Console.WriteLine(exception);
}
}
}
// Writes to CSV file from List
public void SaveGimpiesToCSV(List<Gimpies> gimpies)
{
// using (var mem = new MemoryStream())
// using (var writer = new StreamWriter(mem))
using (var writer = new StreamWriter("gimpies.csv"))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
csvWriter.Configuration.Delimiter = ";";
csvWriter.Configuration.HasHeaderRecord = true;
csvWriter.Configuration.AutoMap<Gimpies>();
csvWriter.WriteHeader<Gimpies>();
csvWriter.WriteRecords(gimpies);
writer.Flush();
// var result = Encoding.UTF8.GetString(mem.ToArray());
// Console.WriteLine(result);
}
}
}
}
But when I write to the existing csv file I get the first three users again! See the result:
username,email,password,userrole,
Inkoop,inkoop@gimpies.nl,123,purchase
Verkoop,verkoop@gimpies.nl,123,sales
Beheer,beheer@gimpies.nl,123,admin
Inkoop,inkoop@gimpies.nl,123,purchase
Verkoop,verkoop@gimpies.nl,123,sales
Beheer,beheer@gimpies.nl,123,admin
Bas,bas@bas.nl,123,admin
Here you see I added the user Bas, but Inkoop and Verkoop and Beheer are added again.
I can't find what I need to delete or change in my code.
To be sure here is my Program.cs:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Globalization;
using System.Linq;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
class Program
{
static void Main(string[] args)
{
// List of default users
// List<User> users = UserList.DefaultUsers();
// Working on it... Try to read csv file first and try to read list from method in UserList.cs
// UserList ul = new UserList();
List<User> users = UserList.LoadUsersFromCSV();
// List<User> users =
// ul.LoadUsersFromCSV(users);
// Create login instance
LoginManager loginMgr = new LoginManager();
// Create stock instance
Stock stock = new Stock();
Start:
// Welcome message
Console.WriteLine("Welcome to the Gimpies Console Application! Choose 1 to login or 2 to exit this application:");
// Get input from user
string input = Console.ReadLine();
// Set to false to check if login fails or not
bool successfull = false;
while (!successfull)
{
if(input == "1")
{
Console.WriteLine("Enter your username:");
string username = Console.ReadLine();
Console.WriteLine("Enter your password:");
string password = Console.ReadLine();
foreach (User user in users)
{
if (username == user.username && password == user.password && user.userrole == "admin")
{
// Create Admin instance to be able to call methods in that class
Admin am = new Admin();
// Calling the method in Admin.cs to start Menu logic
am.AdminLoggedIn(users);
successfull = true;
break;
}
if (username == user.username && password == user.password && user.userrole == "purchase")
{
// Create Purchase instance to be able to call methods in that class
Purchase pc = new Purchase();
// Calling the method in Purchase.cs to start Menu logic
pc.PurchaseLoggedIn(users);
successfull = true;
break;
}
if (username == user.username && password == user.password && user.userrole == "sales")
{
// Create Sales instance to be able to call methods in that class
Sales sl = new Sales();
// Calling the method in Sales.cs to start Menu logic
sl.SalesLoggedIn(users);
successfull = true;
break;
}
}
if (!successfull)
{
Console.WriteLine("Your username or password is incorrect, try again !!!");
}
}
else if (input == "2")
{
Environment.Exit(-1);
}
else if (input == "3")
{
FileOperations fo = new FileOperations();
// Calling the method from FileOperations.cs to write the List here to a CSV file
fo.WriteUsersToCSV(users);
goto Start;
}
else if (input == "4")
{
FileOperations fo = new FileOperations();
// Calling the method from FileOperations.cs to write the List here to a CSV file
fo.ReadUsersFromCSV();
goto Start;
}
else
{
Console.WriteLine("Try again !!!");
break;
}
}
// // Loop over stored users within instances inside the list where users are added
// foreach (User user in users)
// {
// if(loginMgr.Login(user))
// {
// // Login successfull
// Console.WriteLine("Login user " + user.UserName);
// }
// else
// {
// // Not successfull
// }
// }
}
}
}
And my GitLab repo: https://gitlab.com/marianydesign/gimpiesconsoleoocsvlist
I see two options for you. Be sure you only implement one of the two options.
Option #1 (the option your code is trying to implement), you can append the new records to the file data. This option will require you to keep track of what's in the file already so you can exclude writing of records already in the file.
Option #2, you can overwrite the file each time with the complete user list. No appending just full file write each time.
Implement Option #1:
This option only requires a change to inside your else if (input == "3")
condition. Update the condition so it compares the list to be written with what is already in the file, and excluding from writing any Users
already in the file...
else if (input == "3")
{
FileOperations fo = new FileOperations();
// get existing users from file
List<User> userInFile = UserList.LoadUsersFromCSV();
// remove existing users from update list to create final list for writing
List<User> finalList = users.Where(u => !userInFile.Any(uf => uf.email.Equals(u.email, StringComparison.InvariantCultureIgnoreCase))).ToList();
fo.WriteUsersToCSV(users);
goto Start;
}
OR
Implement Option #2:
This options requires a change to your WriteUsersToCSV
method.
public void WriteUsersToCSV(List<User> users)
{
// overwrite the file each time; indicated by the `false` parameter
using (var writer = new StreamWriter("users.csv", false))
using (var csvWriter = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
// csvWriter.Configuration.HasHeaderRecord = false; // commented out as we write the whole file every time including the header
csvWriter.WriteRecords(users);
Console.WriteLine("New user added to users.csv");
}
}