I am trying to show database values assigned to a List in C# but am running into an issue when trying to show them. Instead of what I want it to show, it shows this: System.Collections.Generic.List`1[System.String]
Here is my code:
public List<string>[] selectQuery(string query)
{
// create a list to hold the firt name, last name, and password
List<string>[] list = new List<string>[4];
list[0] = new List<string>(); // will hold the first name
list[1] = new List<string>(); // will hold the last name
list[2] = new List<string>(); // will hold the username
list[3] = new List<string>(); // will hold the password
if (this.openDbConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, this.connection);
MySqlDataReader dr = cmd.ExecuteReader();
// read the data and store it in the list
while (dr.Read())
{
list[0].Add(dr["first_name"] + "");
list[1].Add(dr["last_name"] + "");
list[2].Add(dr["username"] + "");
list[3].Add(dr["password"] + "");
}
// close reading the data operator
dr.Close();
// close connection
this.connection.Close();
// return the list of results to be displayed
return list;
}
else
{
return list;
}
}
List<string>[] data = db.selectQuery("SELECT first_name, last_name, username, password FROM member WHERE username = '" + name + "'" + " AND password = PASSWORD('" + pass + "')");
if (data != null)
{
// assign the username, password, first and last name to the session variables
Session["first_name"] = data[0].ToString();
Session["last_name"] = data[1].ToString();
Session["username"] = data[2].ToString();
Session["password"] = data[3].ToString();
// redirect to member page
Response.Redirect("members.aspx", false);
}
and the html is:
<tr>
<td id="user"><%=Session["username"].ToString()%></td>
<td id="greeting"><%=Session["first_name"].ToString()%></td>
</tr>
Any help would be appreciated!
Thanks!
This is so much more complex then it needs to be. Create an object:
public class User
{
public string first_name { get; set; }
public string last_name { get; set; }
public string username { get; set; }
public string password { get; set; }
public User()
{
}
}
then in your code:
public User selectQuery(string query)
{
User myuser = new User();
//use this if you want to create a List of users and change the method type to "List<User>" and the return to userList.
List<User> userList = new List<User> ();
if (this.openDbConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, this.connection);
MySqlDataReader dr = cmd.ExecuteReader();
// read the data and store it in the list
while (dr.Read())
{
myuser.first_name = dr["first_name"] + "";
myuser.last_name= dr["last_name"] + "");
myuser.username = dr["username"] + "");
myuser.password = dr["password"] + "");
//use the below line only if you are expecting to return multiple users
userList.Add(myuser);
}
// close reading the data operator
dr.Close();
// close connection
this.connection.Close();
// return the list of results to be displayed
return myuser;
}
else
{
return myuser;
}
}
finally you just call the method then access the properties of the returned value
User myuser = db.selectQuery("blah");
if (data != null)
{
// assign the username, password, first and last name to the session variables
Session["first_name"] = myuser.first_name.ToString();
Session["last_name"] = myuser.last_name.ToString();
Session["username"] = myuser.username.ToString();
Session["password"] = myuser.password.ToString();
}
etc or if your returning a list do the following
List<User> myusers = db.selectQuery("blah")
if(!myusers.Count == 1) //this will let you check if it returns multiple users for some reason
{
Session["first_name"] = myusers[0].first_name.ToString();
Session["last_name"] = myusers[0].last_name.ToString();
Session["username"] = myusers[0].username.ToString();
Session["password"] = myusers[0].password.ToString();
}
Related
I am doing a simple project for school where I have to create a login form and make it so when a person logs in it then shows their profile with all their user information. So how would I code the textboxes in windows forms C# so when a person logs in the textboxes show information gathered from database of person who just logged in.
This is the code for the login form.
OleDbConnection connection = new OleDbConnection(); connection.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\RAV21001310\\OneDrive\\Database1.accdb;";
connection.Open();
OleDbCommand command = new OleDbCommand();
command.Connection = connection;
command.CommandText = "select * from tblUser where Username= '"+username.Text+"' and Password= '"+password.Text+"'";
OleDbDataReader reader = command.ExecuteReader();
int count = 0;
while (reader.Read())
{
count = count + 1;
}
if (count == 1)
{
MessageBox.Show("Username and password is correct");
var profile = new profile();
}
if (count > 1)
{
MessageBox.Show("Duplicate username and password");
}
else
{
MessageBox.Show("Username or password incorrect");
}
connection.Close();
As I said in the comments, always use parameters in your query strings. Also, since OleDbDataReader is forward reading only, what I would do is create a new user and add to a list for each record returned. Then, if you only get one record, use that user data to populate the form. One other major flaw in your code... You are storing passwords as plain text in the database. The best practice is to encrypt/hash the password using one-way encryption and only store the hash in the database. Everytime the user enters a password at login, hash it using the same algorithm and compare it against the hash stored in the DB.
Here's an example incorporating Using (suggested by #Flydog57) and Parameters. But I'm not showing how to hash and store encrypted passwords.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.OleDb;
public class Program
{
public static void Main()
{
using (OleDbConnection connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\RAV21001310\\OneDrive\\Database1.accdb;"))
{
connection.Open();
using (OleDbCommand command = new OleDbCommand("SELECT * FROM tblUser WHERE Username=#Username AND Password=#Password", connection))
{
command.Parameters.AddWithValue("#Username", username.text);
command.Parameters.AddWithValue("#Password", password.text);
using (OleDbDataReader reader = command.ExecuteReader())
{
int count = 0;
List<User> UserList = new List<User>();
while (reader.Read())
{
count = count + 1;
User user = new User() {
Username = reader.GetString(1),
FirstName = reader.GetString(2),
LastName = reader.GetString(3),
DateCreated = reader.GetDateTime(4)
};
UserList.Add(user);
}
if (count == 1)
{
//Alert User
MessageBox.Show("Username and password is correct");
//Create an instance of the ProfileForm and populated it with the User data.
var ProfileForm pf = new ProfileForm(UserList[0]);
//Show the Profile Form as a modal window.
pf.ShowDialog();
}
if (count > 1)
{
MessageBox.Show("Duplicate username and password");
}
else
{
MessageBox.Show("Username or password incorrect");
}
}
}
connection.Close();
}
}
}
//This is a class to hold user data.
public class User {
public string Username { get; set; } = "";
public string Password { get; set; } = "";
public string FirstName { get; set; } = "";
public string LastName { get; set; } = "";
public DateTime DateCreated { get; set; } = DateTime.MinValue;
}
This is a quick sample of the code-behind for a "ProfileForm". When you verify the user is authenticated, then create an instance of the ProfileForm, populate it with the userdata, then show the form to the user. There are many other ways to populate a profile form and handle updates to user data, this is just one example.
public class ProfileForm : Form
{
public User User
{
get
{
//When you get the User, update all the user data from text boxes.
User.FirstName = firstnameTextBox.Text;
User.LastName = lastnameTextBox.Text;
//return the newly updated User variable.
return User;
}
set
{
//When we write new data to the form User variable,
//populate each relevant text box on the form.
usernameTextBox.Text = User.Username;
firstnameTextBox.Text = User.FirstName;
lastnameTextBox.Text = User.LastName;
}
}
public ProfileForm(User User) {
this.User = User;
}
}
I have multiple session variables, which both won't accept any values given to them by other variables. I have tried to debug and have found nothing. Here is the function I am using...
public void logIn(object sender, EventArgs e) //triggers when login button is clicked
{
db_connection(); //connects to database using above function
string emailAddress = email.Text.ToString();
string passwordR = password.Text.ToString(); //email and password are converted to variables
DataTable table = new DataTable();
MySqlCommand select = new MySqlCommand("SELECT personID, address_addressID from person WHERE email='" + emailAddress + "' and password = '" + passwordR + "'", connect); //brings back the person ID if user details are correct
using (MySqlDataAdapter adapter = new MySqlDataAdapter(select))
{
adapter.Fill(table);
string sessionVar = table.Rows[0]["personID"].ToString();
Session["personID"] ="";
Session["personID"] = sessionVar;
int sessionVarAddress = Int32.Parse(table.Rows[0]["address_addressID"].ToString());
Session["address_addressId"] = sessionVarAddress;
if (table.Rows.Count != 0)
{
if (Session["personID"] != null) //if the person ID is present do this following statement
{
hideDiv.Visible = false;
}
Response.Redirect("myAccount.aspx"); // if user logs in successfully redirect to my account pag
}
else
{
Response.Redirect("index.aspx"); //if login fails, home page is returned
}
connect.Close();
}
}
I'm implementing a method to return the result set that generated from the query and assign it to a string list. I have set to assign the id (id is a primary key) and name of selected db table line to index 0 and 1 in the string list. The code of that as follows,
public List<string>[] getTrafficLevel()
{
string query = "select * from traffictimeinfo where startTime<time(now()) and endTime>time(now());";
List<string>[] list = new List<string>[2];
list[0] = new List<string>();
list[1] = new List<string>();
if (this.openConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataReader dataReader = cmd.ExecuteReader();
while (dataReader.Read())
{
list[0].Add(dataReader["timeslotid"] + "");
list[1].Add(dataReader["timeslotname"] + "");
}
dataReader.Close();
this.closeConnection();
return list;
}
else
{
return list;
}
}
What I want to know is how can i assign this values in two indexes into two string variables.
the method that i tried is as follows, is there anyone who knows how to implement this.. Thanks in advance..
public void predictLevel(List<String>resList)
{
string trafficTime, trafficLevel;
List<string>[]ansList = getTrafficLevel();
ansList[0] = # want to assign the string value into trafficTime string variable
ansList[1].ToString = # want to assign the string value into trafficLevel string variable
}
Have you considered using List of Tuples instead?
public List<Tuple<string,string>> getTrafficLevel()
{
string query = "select * from traffictimeinfo where startTime<time(now()) and endTime>time(now());";
List<Tuple<string,string>> list = new List<Tuple<string,string>>();
if (this.openConnection() == true)
{
MySqlCommand cmd = new MySqlCommand(query, connection);
MySqlDataReader dataReader = cmd.ExecuteReader();
while (dataReader.Read())
{
list.Add(new Tuple<string,string>(dataReader["timeslotid"] + "", dataReader["timeslotname"] + ""));
}
dataReader.Close();
this.closeConnection();
return list;
}
else
{
return list;
}
}
And your predictLevel method would be -
public void predictLevel(List<String>resList)
{
string trafficTime, trafficLevel;
List<Tuple<string,string>> ansList = getTrafficLevel();
trafficTime = ansList[0].Item1;
trafficLevel = ansList[0].Item2;
}
here is my login button click code. i have set the session["Username"] to the input of the customer in txtUser.text.
protected void btn_Login_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection("Data Source = 'PAULO'; Initial Catalog=ShoppingCartDB;Integrated Security =True");
conn.Open();
string checkuser = "select count(*) from UserData where Username = '" + txtUser.Text + "'";
SqlCommand scm = new SqlCommand(checkuser, conn);
int temp = Convert.ToInt32(scm.ExecuteScalar().ToString());
conn.Close();
if (temp == 1)
{
conn.Open();
string checkPassword = "select Password from UserData where Username ='" + txtUser.Text + "'";
SqlCommand passCom = new SqlCommand(checkPassword, conn);
string password = passCom.ExecuteScalar().ToString().Replace(" ", "");
if (password == txtPassword.Text)
{
Session["Username"] = txtUser.Text;
Response.Write("<script>alert('Record saved successfully')</script>");
Response.Redirect("OrderNow.aspx");
}
else
{
lblcrederror.Text = ("Credentials dont match");
}
and here is where i call it. (ordernow.aspx) this is where the customer is redirected when he/she places and order. im planning to pass the values of the customer (email address username phone number) into the textboxes before submitting the order.
private void GetMyCart()
{
DataTable dtProducts; // declare data table = dtProducts.
if (Session["MyCart"] != null) // check whether session is null or not.
{
dtProducts = (DataTable)Session["MyCart"]; //if session is not null, assign all session to dtproducts.
}
else
{
dtProducts = new DataTable(); //if session is null, create new datatable (dtproducts).
}
if (dtProducts.Rows.Count > 0) // if rows.count is greater than 0, it means there is a value records from the session.
{
txtCustomerName.Text = Session["Username"].ToString();
//txtCustomerPhoneNo.Text = Session["Contact"].ToString();
//txtCustomerEmailID.Text = Session["Email"].ToString();
//txtCustomerAddress.Text = Session["DeliveryAddress"].ToString();
txtTotalProducts.Text = dtProducts.Rows.Count.ToString(); // this will display all of the chosen records
btnIslandGas.Text = dtProducts.Rows.Count.ToString();
dlCartProducts.DataSource = dtProducts;
dlCartProducts.DataBind();
UpdateTotalBill();
pnlMyCart.Visible = true;
pnlCheckOut.Visible = true;
pnlEmptyCart.Visible = false;
pnlCategories.Visible = false;
pnlProducts.Visible = false;
pnlOrderPlaceSuccessfully.Visible = false;
}
else // session is empty
{
pnlEmptyCart.Visible = true; // since session is empty and there is no value record, pull up the empty shopping cart page
pnlMyCart.Visible = false;
pnlCheckOut.Visible = false;
pnlCategories.Visible = false;
pnlProducts.Visible = false;
pnlOrderPlaceSuccessfully.Visible = false;
dlCartProducts.DataSource = null;
dlCartProducts.DataBind();
txtTotalProducts.Text = "0"; // total products, price and number logo is set to 0.
txtTotalPrice.Text = "0";
btnIslandGas.Text = "0";
}
the Session["Username"] is working. meaning it is binded with the txtCustomername.text. but the rest are not working (email,address,phone no.)
As I understand, what you are doing is that on your login page in case the user is authenticated i.e in your code when the passwords are successfully matched. The Session variables viz. Contact, Email, DeliveryAddress are not set at all. Only Name is set.
After this you make redirection to ordernow.aspx page. Hence you don't get them there. You only get one you set.
In register page you set the other Session variables but you have to understand that it's only after that they will be available in ordernow.aspx
So if you go from register to ordernow.aspx you will get the values but not when you go from login page to ordernow.aspx
You need to set the other Session variables as well in the Login page before making redirection to the ordernow page and accessing them there.
Update:
You are only getting password from the database on the basis of the username, but instead you need to get the whole user record with other details like email, contact , address as well. Then match the password, if it matches you have your user and all his other details with which you need to set Session variables.
Update Second:
if (temp == 1)
{
conn.Open();
string checkPassword = "select * from UserData where Username ='" + txtUser.Text + "'";
SqlCommand passCom = new SqlCommand(checkPassword, conn);
using (SqlDataReader oReader = passCom.ExecuteReader())
{
while (oReader.Read())
{
if(oReader["UserName"].ToString().Replace(" ", "") == txtPassword.Text.Trim())
{
Session["Username"] = oReader["FirstName"].ToString();
Session["Contact"] = oReader["Contact"].ToString();
Session["Email"] = oReader["Email"].ToString();
Session["DeliveryAddress"] = oReader["DeliveryAddress"].ToString();
Response.Redirect("OrderNow.aspx");
}
else
{
lblcrederror.Text = ("Credentials dont match");
break;
}
}
myConnection.Close();
}
}
I have a check button that will fetch the month and year in combo box:
private void cmdSend_Click(object sender, System.EventArgs e)
{
List<string>[] list;
list = dbConnect.Select(month_list.SelectedItem.ToString(), year_list.SelectedItem.ToString());
printer_info.Rows.Clear();
for (int i = 0; i < list[0].Count; i++)
{
int number = printer_info.Rows.Add();
printer_info.Rows[number].Cells[0].Value = list[0][i];
printer_info.Rows[number].Cells[1].Value = list[1][i];
printer_info.Rows[number].Cells[2].Value = list[2][i];
printer_info.Rows[number].Cells[3].Value = list[3][i];
}
}
The check button then pass the month and year to the select statement function:
public List<string>[] Select(string month,string year)
{
string query = "SELECT * FROM page_counter WHERE month = '#month' AND year = #year;";
//Create a list to store the result
List<string>[] list = new List<string>[4];
list[0] = new List<string>();
list[1] = new List<string>();
list[2] = new List<string>();
list[3] = new List<string>();
//Open connection
if (this.OpenConnection() == true)
{
//Create Command
MySqlCommand cmd = new MySqlCommand(query, connection);
cmd.Parameters.Add("#month",MySqlDbType.VarChar);
cmd.Parameters.Add("#year", MySqlDbType.Year);
cmd.Parameters["#month"].Value = month;
cmd.Parameters["#year"].Value = year;
//Create a data reader and Execute the command
MySqlDataReader dataReader = cmd.ExecuteReader();
//Read the data and store them in the list
while (dataReader.Read())
{
list[0].Add(dataReader["id"].ToString() + "");
list[1].Add(dataReader["month"].ToString() + "");
list[2].Add(dataReader["year"].ToString() + "");
list[3].Add(dataReader["page_count"].ToString() + "");
}
//close Data Reader
dataReader.Close();
//close Connection
this.CloseConnection();
//return list to be displayed
return list;
}
the data will then display on the gridview where all column are specified by default in page designer:
When I run the code, it doesnt have any error, but theres no value display on the gridview. Is there any mistake I make? Im newbie in c# winform,please advise.
I think you have two mistakes.First you should remove the single-quotes from query string:
string query = "SELECT * FROM page_counter WHERE month = #month AND year = #year;"
Because when you use single-quotes your parameter names treated as actual value.Secondly, I would highly recommend you to use a class for your item instead of a List<string>[].The class would look like this:
public class Data
{
public int Id { get; set; }
public string Month { get; set; }
public string Year { get; set; }
public int PageCount { get; set; }
}
Then create a List<Data> and populate it like this:
var dataList = new List<Data>();
while (dataReader.Read())
{
var item = new Data();
item.Id = Convert.Toınt32(dataReader["id"]);
item.Month = dataReader["month"].ToString();
item.Year = dataReader["year"].ToString();
item.PageCount = Convert.ToInt32(dataReader["page_count"]);
dataList.Add(item);
}
return dataList;
Then ofcourse change the returning type of your method:
public List<Data> Select(string month,string year)
Then all you need to do is set the DataSource property:
var list = dbConnect.Select(month_list.SelectedItem, year_list.SelectedItem);
printer_info.DataSource = list;