I am looking for the solution to save and reload what I enter into my text boxes or what I filled in my ComboBoxes. Here is the code I current have, but I am not 100% sure it is all correct. I am only posting the code I need help with. If you need the entire batch of code I can post it, but I did not think it was relevant to what I am asking for. This is what I have done so far, which I am not sure it will actually save the info that is typed in, and I am completely unsure as to what to put in the loadLastBtn method. I Just want it to be saved to memory even when the textbox texts have changed and then I want to be able to retrieve that from memory when I hit the loatLastbtn.
private void submitBtn_Click(object sender, EventArgs e)
{
List<Members> lstMembers = new List<Members>();
if (string.IsNullOrEmpty(firstNameTxt.Text) || string.IsNullOrEmpty(lastNameTxt.Text)
|| string.IsNullOrEmpty(userNameTxt.Text) ||
string.IsNullOrEmpty(passwordTxt.Text) || string.IsNullOrEmpty(confPassTxt.Text)
|| string.IsNullOrEmpty(majorBox.Text) || string.IsNullOrEmpty(specialtyBox.Text))
{
MessageBox.Show("You must enter in all fields before moving forward");
}
else
{
//would this save my data to the array and how can I reload this?
Members m1 = new Members(firstNameTxt.Text, lastNameTxt.Text, userNameTxt.Text,
passwordTxt.Text, confPassTxt.Text, majorBox.Text,
specialtyBox.Text);
lstMembers.Add(m1);
}
}
private void loadLastBtn_Click(object sender, EventArgs e)
{
for(int i = 0; i < lstMembers.Count; i++)
{
firstNameTxt.Text = lstMembers[i].FirstName;
lastNameTxt.Text = lstMembers[i].LastName;
userNameTxt.Text = lstMembers[i].UserName;
passwordTxt.Text = lstMembers[i].Password;
confPassTxt.Text = lstMembers[i].ConfPassword;
majorBox.Text = lstMembers[i].Major;
specialtyBox.Text = lstMembers[i].Specialty;
}
}
Here is the user object I created. I am just unsure how to call it now when I want to save and reload.
class Members
{
private string firstName;
private string lastName;
private string userName;
private string password;
private string confPassword;
private string major;
private string specialty;
public Members(string firstName, string lastName, string userName, string password,
string confPassword, string major, string specialty)
{
this.firstName = firstName;
this.lastName = lastName;
this.userName = userName;
this.password = password;
this.confPassword = confPassword;
this.major = major;
this.specialty = specialty;
}
public string FirstName
{
get
{
return firstName;
}
set
{
FirstName = firstName;
}
}
public string LastName
{
get
{
return lastName;
}
set
{
LastName = lastName;
}
}
public string UserName
{
get
{
return userName;
}
set
{
UserName = userName;
}
}
public string Password
{
get
{
return password;
}
set
{
Password = password;
}
}
public string ConfPassword
{
get
{
return confPassword;
}
set
{
ConfPassword = confPassword;
}
}
public string Major
{
get
{
return major;
}
set
{
Major = major;
}
}
public string Specialty
{
get
{
return specialty;
}
set
{
Specialty = specialty;
}
}
I would suggest creating a 'POCO' (Plain old c# object) or struct that will hold your data.
When you want to save it, just serialize it to disk (either using MS Serialization (more here, or by using JSON serialize method (more here).
This way, you don't worry about what the user might have entered (less worries about sanitizing the data and making sure he didn't use your escape character).
Well, most common way to do it without any hard implementation would be writing all of your variables with ';' between them within a file. Then read it from file and re-assign it into your form elements when user press down a button.Check this guide to how to write into file:
https://msdn.microsoft.com/en-us/library/8bh11f1k.aspx
I'll give an simple example:
For example my form consist of username and password TextFields. After user entered them and pressed login, I save them into file for next time user logs in, this method will save it.
public void save(){
String username = txtUsername.Text;
String password = txtPassword.Text;
File.WriteAllText(path, username + ";" + password);
}
public void load(){
String parameters = File.ReadAllText(path);
String[] splitted = parameters.split(';');
txtUsername.Text = splitted[0];
txtPassword.Text = splitted[1];
}
Related
I am trying to write a c# program to make a Bank system with users creating bank accounts. And I want to be able to save these accounts given through the console to an excel file so it can retrieve them later if needed.
I followed a tutorial on how to do that and made minor adjustments to the code but when I try to run the program with some test accounts it writes them as blank accounts with no data and I can't see why it would do this.
public class Account
{
protected static int count = 1;
protected int accountNum;
protected string fName;
protected string lName;
protected int idNumber;
protected string address;
protected DateOnly birthday = new();
protected bool flag;
Savings.SpendingRef = Spendings(accountNum);
public Account(string fn, string ln, int idnum, string add, DateOnly bd)
{
//System.Threading.Interlocked.Increment(ref count);
this.accountNum = count++;
fName = fn;
lName = ln;
idNumber = idnum;
address = add;
birthday = bd;
flag = false;
}
public int AccountNum{get;}
public string FName{get; set;}
public string LName{get; set;}
public int IdNumber{get; set;}
public string Address{get; set;}
public DateOnly Birthday{get;}
public bool Flag{get; set;}
public string GetAccount(){
string s = "--------------------------------\n";
s += "Account Number :" + accountNum + "\nAccount belonging to :" + fName + " " + LName + "\nID Number :" + IdNumber + "\nAddress :" + address + "\nBirthday : " + birthday + "\nAccount blocked? :" + flag;
s += "\n--------------------------------\n";
Console.WriteLine(s);
return s;
}
}
Here is how the account class is implemented
static async Task Main(string[] args)
{
ExcelPackage.LicenseContext = LicenseContext.NonCommercial;
var file = new FileInfo(#"..\..\..\SavedAccounts.XLSX");
//Other code not important
var Accounts = GetSetupData();
await SaveExcelFile(Accounts, file);
}
private static List<Account> GetSetupData()
{
List<Account> output = new()
{
new Account("Jerome", "Dupret", 42069, "68 rue des ecoles", new DateOnly(1999, 08, 10)),
new Account("Deborah", "Pierre", 69420, "68 rue des ecoles", new DateOnly(2000, 02, 18)),
};
return output;
}
Here are the test accounts I want to be inserted.
private static async Task SaveExcelFile(List<Account> accounts, FileInfo file)
{
DeleteIfExists(file);
using var package = new ExcelPackage(file);//basically a Dispose method to get rid of any useless data
var ws = package.Workbook.Worksheets.Add("AccountData");
var range = ws.Cells["A1"].LoadFromCollection(accounts, true);
range.AutoFitColumns();
await package.SaveAsync();
}
And this is where the call and the write function itself happen.
I used console Writes at every step to check if the accounts lose info at any time but they never do, I'm confused as to why it isn't sent properly.
It looks like you never set your public properties such as Fname, either you need to set them in the constructor or make the getter get the protected field.
for example
protected string fName;
public string FName
{
get
{
return fName;
}
set
{
fName = value;
}
}
This needs to be done on all the public fields so they all get the field that gets set in the constructor.
The set is not required but if you dont use it FName and fName can become diffrent values since fName is only set in the constructor.
I am using the following Code
public class GetTabelRealizari : ControllerBase
{
public class Realizare
{
String user;
String denumire;
String incasari;
public Realizare(String user, String denumire, String incasari)
{
this.user = user;
this.denumire = denumire;
this.incasari = incasari;
}
public String getUser()
{
return user;
}
public void setUser(String user)
{
this.user = user;
}
public String getDenumire()
{
return denumire;
}
public void setDenumire(String denumire)
{
this.denumire = denumire;
}
public String getIncasari()
{
return incasari;
}
public void setIncasari(String incasari)
{
this.incasari = incasari;
}
}
[HttpPost]
public string Post([FromBody] string[] value)
{
//SSMS connection
string connectionString = "Data Source=DESKTOP-QKC0G7V;Initial Catalog=Restaurant_gest;Integrated Security=True";
SqlConnection connection = new SqlConnection(connectionString);
connection.Open();
List<Realizare> realizari = new List<Realizare>();
double incasari;
String incasariString;
SqlCommand command = new SqlCommand("SELECT Users.Username," +
" Tip_Nota_Plata.Denumire," +
" sum(Nota_plata.Suma) as Incasari" +
" from Users" +
" INNER JOIN Nota_plata" +
" INNER JOIN Comandas" +
" ON Nota_plata.Id_comanda = Comandas.Id" +
" ON Comandas.User_Id = Users.Id" +
" INNER JOIN Tip_Nota_Plata" +
" ON Tip_Nota_Plata.Id = Nota_plata.Id_tip_nota" +
" Group by Username, Tip_Nota_Plata.Denumire", connection);
using (SqlDataReader reader = command.ExecuteReader())
{
while (reader.Read())
{
incasari = (double)reader["Incasari"];
incasariString = incasari.ToString("#.##");
realizari.Add(new Realizare(reader["Username"].ToString(), reader["Denumire"].ToString(), incasariString));
}
}
return JsonConvert.SerializeObject(realizari);
//return "salut";
}
}
And I am receiving an empty JsonObject. Why?
[{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{},{}]
I keep trying to make it work and I cannot. The list has the objects, i can test it with Console.Writeline(realizari[0].getDenumire()) and it works. I can also serialize a list of strings, it just doesn`t work for objects.
Because the object has no serializable properties.
I'm going to guess you are a Java developer based on this:
String user;
public String getUser()
{
return user;
}
public void setUser(String user)
{
this.user = user;
}
C# has "properties" which, while they compile down to methods very similar to this, the syntax in C# is a bit different. All of the above code can be simplified to a property:
public String User { get; set; }
The usage then becomes simpler as well, allowing for assignments instead of calling a method:
someObject.User = someUser;
In cases where you want to add logic to your getter/setter, you can expand the "auto implemented property" above into a manual one:
private string user;
public string User
{
get { return user; }
set { user = value; }
}
The get and set syntax still tells the compiler that this is a property, but within those blocks you can write any method logic you like. (In the setter value is a keyword for the value being assigned to the property.)
I am trying to send form data to a confirmation page where you would enter your cc info to complete the transaction. I add all the information to a list that i will later code as hidden fields on the new form to send the information off as paid. However when I do a repsonse.write to see what the information stored is. i always get the same name over and over. not exactly sure where i am missing it. Thanks for your help!
protected void Page_Load(object sender, EventArgs e)
{
if (Request.HttpMethod == "POST"){
formData attendee = new formData();
NameValueCollection nvc = Request.Form;
List<formData> attendees = new List<formData>();
if (!string.IsNullOrEmpty(nvc["fn1"]))
{
var fn = nvc["fn1"];
var ln = nvc["ln1"];
var email = nvc["email1"];
var wife = nvc["wife1"];
var luncheon = nvc["lucheon1"];
attendee.firstName = fn; attendee.lastName = ln; attendee.email = email; attendee.wife = wife; attendee.luncheon = luncheon;
attendees.Add(attendee);
}
if (!string.IsNullOrEmpty(nvc["fn2"]))
{
var fn = nvc["fn2"];
var ln = nvc["ln2"];
var email = nvc["email2"];
var wife = nvc["wife2"];
var luncheon = nvc["lucheon2"];
attendee.firstName = fn; attendee.lastName = ln; attendee.email = email; attendee.wife = wife; attendee.luncheon = luncheon;
attendees.Add(attendee);
}
foreach(var person in attendees)
{
Response.Write(person.firstName.ToString());
Response.Write(person.lastName.ToString());
Response.Write(person.email.ToString());
Response.Write(person.wife.ToString());
Response.Write(person.luncheon.ToString());
}
}
}
public class formData
{
public string firstName { get; set; }
public string lastName { get; set; }
public string email { get; set; }
public string wife { get; set; }
public string luncheon { get; set; }
}
}
I assume your array of Attendees is going to be of a data type like this... each attendee has a {fn, ln, email, wife, and luncheon} property. Looks like they're stored in the POST like {fn1, ln1, email1, wife1, luncheon1} is attendee(0), {fn2, ln2, email2, wife2, luncheon2} is attendee(1), etc.
You might try looping like this
var count = 1;
while (!string.IsNullOrEmpty(nvc["fn" + count]))
{
attendee(count).firstname=nvc["fn" + count]
attendee(count).lastname=nvc["ln" + count]
//...for the rest of the fields
count++; //be sure and increment count
}
Until there's data fn# that is null, it keeps looping through and creating attendees.
You are creating the list in the Page_Load event. The Page_Load event fires each time the page loads, postback or not and recreating the list every time that event fires.
You can create and use a session variable. As an example:
protected void Page_Load(object sender, EventArgs e)
{
List<formData> attendees;
if(Session["attendees"] == null)
{
attendees = new List<formData>();
// your logic logic ...
Session["attendees"] = attendees;
}
else
{
var attendees = (List<formData>)Session["attendees"];
// your logic ...
Session["attendees"] = attendees;
}
}
I'd also consider breaking your code out a bit. Perhaps putting the code that adds to the list in a separate method.
ASP.NET Session State Overview.
I created a class I named Cashiers(shown below). I can create new instances through code no problem. What I can not do is have a user input a string value into a string variable I named CashierLOgInNName. So if the user inputs the value as DSPR I want to be able to create a new cashier object by that name, or the equivalent of
Cashiers DSPR = new Cashiers();
I've included the parts of my code that pertain to this question. Ideally if I could have the line or lines of code that would enable me to have this work and why that be excellent.
public class Cashiers
{
public int CashierID;
public int Password;
public string FirstName;
public string LastName;
public void SetCashiers(int CashierID, int Password,string FirstName, string LastName )
{
this.CashierID = CashierID;
this.Password = Password;
this.FirstName = FirstName;
this.LastName = LastName;
}
public void SetNewCashier(int CashierID, int Password, string FirstName, string LastName)
{
//Cashiers NewCashier = new Cashiers();
this.CashierID = CashierID;
this.Password = Password;
this.FirstName = FirstName;
this.LastName = LastName;
}
}
Console.WriteLine("enter New Log in name");
string CashierLOgInNName = Console.ReadLine();
To more directly answer with your example, building on the best method of using a dictionary (aka Key Value Pair):
Dictionary<String,Cashiers) dictCashiers = new Dictionary<String,Cashiers>();
Console.WriteLine("Enter new login name:");
String CashierLogInName = Console.ReadLine();
Cashiers newCashier = new Cashiers();
dictCashiers.Add(CashierLogInName,newCashier);
//replace constants in the next line with actual user's data, probably input from more ReadLine queries to user?
dictCashiers[CashierLogInName].SetNewCashier(1,2,"Jane","Doe");
You can see dictCashiers[CashierLogInName] accomplishes what I believe you are looking for, and retrieves the Cashiers object associated with that Login ID.
It sounds to me like what you're really looking for is either a database (which is too broad to answer here) or a dictionary.
In a dictionary, you'll be able to store your Cashier objects keyed by a string. You aren't affecting the name of the variable, of course, but you can still use that name in a theoretical context to get at what you're looking for. If you did actually change the name, that would lead to a need for reflection, which is messy and slow.
private Dictionary<string, Cashiers> dict = new Dictionary<string, Cashiers>();
private void Save(string name, [probably some other details?])
{
dict[name] = new Cashiers(); // or whatever
}
private void Print(string name)
{
Console.WriteLine(dict[name]);
}
private void PrintAll()
{
Console.WriteLine(string.Join(Environment.NewLine, dict.Select(c => c.Key + "\t" + c.Value.ToString()));
}
Obviously my implementation here leaves something to be desired, but it shows how you can use it.
I am using properties to allow a single string name to be added to the class Details, I want the property to only accept the string if it can be split into two parts.
The two parts would be the firstName and the LastName. However if the resulting split has 1,0 or more than 2 strings in the array then the input should be deemed invalid and I want to throw a error to whatever code called the property in the first place.
Can error handling be done on properties like this?
If not then what of the following is the preferred way to get data into a class whilst checking for correctness:
Use a method inside the class Details to handle error inputs, make that method boolean.
Continue using properties but have the error checking done by the code that calls the property. I don't like this because I want all the error checking code to be self-contained in the Details class.
.
class Details
{
private string firstName, lastName;
public string Name
{
// name
get { return firstName + " " + lastName; }
set
{
string name = value;
string[] nameArray = name.Split(' ');
firstName = nameArray[0];
lastName = nameArray[1];
}
}
}
EDIT: I am mostly interested in what of the three options is concidered best pratice:
Error check inside properties.
Error check outside class in another class, and then just add the verified inputs to Details
Use a boolean method inside Details to verify the inputs.
I would follow an existing validation framework, such as FluentValidation.
Also, in your specific case, I would have a SetName(string fullName) method that does the parsing and populating.
Why not use exception to capture the error condition.
private string firstName, lastName;
public string Name
{
get { return string.Concat(firstName, " ", lastName); }
set
{
string name = value;
if (string.IsNullOrEmpty(name)) { throw new ArgumentNullException("Name"); }
var nameParts = name.Trim().Split(' ');
if (nameParts.Length != 2) { throw new ArgumentException("Invalid name value"); }
firstName = nameParts[0];
lastName = nameParts[1];
}
}
Just to add my perspective to what others have said, it seems to me that part of the difficulty stems from the fact that you're using a property setter to do something non-trivial (split a string, validate the results, and then store the results in two fields). Generally, properties, especially read/write properties, should only be concerned with getting and setting a single value (using read-only properties to return a simple computed value is common enough too).
If it were me, I'd have separate properties for the first name and last name, with a third computed property for the full name:
class Details
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string FullName
{
get { return string.Concat(this.FirstName, " ", this.LastName); }
}
}
Then you could add a method to set the full name. A method is more appropriate than a property setter for this task, since it's non-trivial and has more potential for problems:
public void SetFullName(string fullName)
{
string[] nameComponents = fullName.split(' ');
if (nameComponents.Length != 2)
{
throw new ArgumentException("The full name must contain a first and last name.");
}
this.FirstName = nameComponents[0];
this.LastName = nameComponents[1];
}
I also want to give a plug for the Code Contracts package. It may be more complication than you're looking for here, but it's a great way of validating input and output in your applications.
So I wouldn't consider data that doesn't meet business logic an exception and thus wouldn't throw one. What I would do is this:
class Details
{
private string firstName, lastName;
public string Name
{
// name
get { return firstName + " " + lastName; }
set
{
string name = value;
string[] nameArray = name.Split(' ');
if(nameArray.Length == 2)
{
firstName = nameArray[0];
lastName = nameArray[1];
}
else
{
firstName = nameArray[0];
lastName = string.Empty;
}
}
}
public bool IsValid()
{
return !string.IsNullOrEmpty(lastName);
}
}
You can then use the name property and then check to see if the name is valid. If not valid, then you can take the appropriate action.
Another option would be to have the validation done in the method calling Details.Name.
EDIT: want to remove what I think is bad advice but keeping so comments make sense, so just striking them out
EDIT2:
You could also do something like this:
class Details
{
private string firstName, lastName;
public string Name
{
get { return firstName + " " + lastName; }
private set;
}
public bool TryParseName(string name)
{
bool isValid = true;
string[] nameParts = name.split(' ');
if(nameParts.Length == 2)
{
firstName = nameParts[0];
lastName = nameParts[1];
}
else
{
isValid = false;
}
return isValid;
}
}
Where you would do
if(details.TryParseName(name))
{
// is valid name
}
else
{
// handle invalid name
}