Issue
I have a simple Console Application that contains a list of 3 users in Program.cs. Within Program.cs I want to call a method in FileOperations.cs
.
First my Program.cs
:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
class Program
{
static void Main(string[] args)
{
// Create user default instances
User user0 = new User("Beheer", "beheer@gimpies.nl", "123");
User user1 = new User("Inkoop", "inkoop@gimpies.nl", "123");
User user2 = new User("Verkoop", "verkoop@gimpies.nl", "123");
// List of users (with a list you can add, get and remove items in the list)
List<User> users = new List<User>();
users.Add(user0);
users.Add(user1);
users.Add(user2);
// Create login instance
LoginManager loginMgr = new LoginManager();
Start:
// Welcome message
Console.WriteLine("Welcome to GimpiesTerminal! Choose 1 to login or 2 to register:");
// Get input from user
string input = Console.ReadLine();
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)
{
Console.WriteLine("You have successfully logged in !!!");
Console.ReadLine();
successfull = true;
break;
}
}
if (!successfull)
{
Console.WriteLine("Your username or password is incorrect, try again !!!");
}
}
else if (input == "2")
{
// Get user input
Console.WriteLine("Enter your username:");
string username = Console.ReadLine();
Console.WriteLine("Enter your email:");
string email = Console.ReadLine();
Console.WriteLine("Enter your password:");
string password = Console.ReadLine();
// Create fresh instance to save input in memory
User user = new User(username, email, password);
// Adds the user to the excisting list
users.Add(user);
successfull = true;
goto Start;
}
else if (input == "3")
{
// Here I want to call the method from FileOperations.cs to write the List here to a CSV file.
}
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 here is my FileOperations.cs
:
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using CsvHelper;
namespace GimpiesConsoleOOcsvListUI
{
public class FileOperations
{
// Handles CRUD within CSV files and able to save them
public void SaveToCSV(User user)
{
using (var mem = new MemoryStream())
using (var writer = new StreamWriter(mem))
using (var csvWriter = new CsvWriter(writer))
{
csvWriter.Configuration.Delimiter = ";";
csvWriter.Configuration.HasHeaderRecord = true;
csvWriter.Configuration.AutoMap<User>();
csvWriter.WriteHeader<User>();
csvWriter.WriteRecords(user);
writer.Flush();
var result = Encoding.UTF8.GetString(mem.ToArray());
Console.WriteLine(result);
}
}
}
}
I get the following errors at line 16 of FileOperations.cs
:
StreamWriter writer
Argument 1: cannot convert from System.IO.StreamWriter
to CsvHelper.ISerializer
And line 23:
User user
Argument 1: cannot convert from GimpiesConsoleOOcsvListUI.User
to System.Collections.IEnumerable
I'm new to C# so I hope you don't mind if it is a simple to solve problem! :-)
Solution
You could try the following piece of code if you want to serialize a single user object and display its serialized header and values:
public void SaveToCSV(List<User> users)
{
var csvConfig = new CsvConfiguration(CultureInfo.CurrentCulture)
{
HasHeaderRecord = true,
Delimiter = ",",
Encoding = Encoding.UTF8
};
using (var mem = new MemoryStream())
using (var writer = new StreamWriter(mem))
using (var csvWriter = new CsvWriter(writer, csvConfig))
{
csvWriter.WriteHeader<User>();
csvWriter.WriteRecords(users);
writer.Flush();
var result = Encoding.UTF8.GetString(mem.ToArray());
Console.WriteLine(result);
}
}
It is using a simple StringWriter
instance needed by the library's CsvWriter
and is using InvariantCulture
info for content serialization. The third parameter leaveOpen
must be set to true
in this case because you're interested in the content of the StringWriter
within the scope of the using
block. Last but not least, you're currently passing a single instance of User
so you have to call WriteRecord
method instead of WriteRecords
.
If you want to write it to the actual file though, you have to do it a bit differently:
public void SaveToCSV(List<User> users)
{
var csvConfig = new CsvConfiguration(CultureInfo.CurrentCulture)
{
HasHeaderRecord = true,
Delimiter = ",",
Encoding = Encoding.UTF8
};
using (var writer = new StreamWriter("path\\to\\your\\file.csv"))
using (var csvWriter = new CsvWriter(writer, csvConfig))
{
csvWriter.WriteHeader<User>();
csvWriter.WriteRecords(users);
}
}
You don't need to call Flush
in the second example because the end of using
block calls it for you and you're not interested in the CSV content within its scope.
Answered By - msmolcic Answer Checked By - Marilyn (PHPFixing Volunteer)
0 Comments:
Post a Comment
Note: Only a member of this blog may post a comment.