I need to create a login that displays user data after login in a gridview / datatable
I'm able to display the username / password but not the user ID that's needed.
I've also tried creating a class where the values gets stored after login
private bool DataValidation(string user, string pass)
{
using (MySqlConnection conn = new MySqlConnection(connectionString))
using (MySqlCommand cmd = new MySqlCommand("SELECT * "+
"FROM member " +
"WHERE username=#user AND password=#pass;", conn))
{
cmd.Parameters.AddWithValue("#user", user);
cmd.Parameters.AddWithValue("#pass", pass);
cmd.Connection = conn;
cmd.Connection.Open();
MySqlDataReader login = cmd.ExecuteReader();
List<Connect> connectList = new List<Connect>();
while (login.Read())
{
Connect connect = new Connect();
connect.username = login.GetString(0);
connect.password = login.GetString(1);
connect.userID = login.GetString(4);
connectList.Add(connect);
}
if(connectList.Count > 0)
{
return true;
}
else
{
return false;
}
}
I'm mostly not sure how to store or display the values after they have been queried
Based on our conversation in the comments, let's focus on this code:
MySqlDataReader login = cmd.ExecuteReader();
if (login.Read())
{
conn.Close();
return true;
}
else
{
conn.Close();
return false;
}
The only thing we are doing here is finding out if login contains any rows. But we are not doing anything with those rows.
Let's try something like this instead:
MySqlDataReader login = cmd.ExecuteReader();
while (login.Read())
{
var something1 = login.GetString(0); // this will get the value of the first column
var something2 = login.GetString(1); // this will get the value of the second column
}
Or, if you are adding the results to an object:
MySqlDataReader login = cmd.ExecuteReader();
List<MyObject> myObjectList = new List<MyObject>;
while (login.Read())
{
MyObject myObject = new MyObject;
myObject.something1 = login.GetString(0); // this will get the value of the first column
myObject.something2 = login.GetString(1); // this will get the value of the first column
myObjectList.Add(myObject);
}
if (myObjectList.Count > 0)
{
return true;
}
else
{
return false;
}
You will need to adjust to meet your needs, but hopefully, this will get you there.
More info here: SqlDataReader.Read Method
Related
In this database table (administration), there are 4 attributes (email, name, password and mobile phone). I need that inside the if I can use each one of them but I don't know how I can access them.
How can I do this?
private void button_login_Click(object sender, EventArgs e)
{
String username, user_password;
username = txt_username.Text;
user_password = txt_password.Text;
try
{
String query = "SELECT * FROM administracao WHERE email = '"+txt_username.Text+"' AND password = '"+txt_password.Text+"'";
SqlDataAdapter sda = new SqlDataAdapter(query, conn);
DataTable dtable = new DataTable();
sda.Fill(dtable);
if (dtable.Rows.Count > 0)
{
// username = txt_username.Text;
// user_password = txt_password.Text;
/* Menuform form2 = new Menuform();
form2.Show();
this.Hide();*/
}
else
{
MessageBox.Show("Invalid Login details", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
txt_username.Clear();
txt_password.Clear();
txt_username.Focus();
}
}
catch
{
MessageBox.Show("Error");
}
finally
{
conn.Close();
}
}
For communication with database I would strongly recommend Entity Framework.
In your case you can use SqlDataReader to get output data from sql query
Code Example:
public void GetData()
{
var query = "your query";
var connectionString = "your connection string";
using (var connection = new SqlConnection(connectionString))
{
var command = new SqlCommand(query, connection);
connection.Open();
SqlDataReader reader = command.ExecuteReader();
try
{
// Iterate all selected rows
while (reader.Read())
{
int value1 = (int)reader["Int column name"];
string value2 = (string)reader["String column name"];
}
}
finally
{
reader.Close();
}
}
}
NOTE:
In real project NEVER store passwords as plaintext. How to do it properly
As people already mentioned in the comments, when you decide to execute query directly from the code NEVER combine query like you did, because of SQL Injection. Use parametrized SqlCommands. How to do it
[UPDATED]
I got a situation here where I need to fetch data from 2 different databases and then combine it into a model. I have an API method I made here that takes care of that but the moment I started working with a second database I got really confused on how I can retrieve more than one item. I'll explain. Here is the code to that method:
private List<FidelityModel> models;
public List<FidelityModel> getFidelityInfo2(string jobID) {
FidelityModel fidelityInfo;
SqlCommand command;
SqlConnection conn;
SqlDataReader reader;
string cjsJobName, ipwNumber, overnight, site;
int packageCount;
DateTime sla;
models = new List<FidelityModel>();
using (conn = new SqlConnection(#"server = [servername]; database = Dropoff; Integrated Security = true;")) {
conn.Open();
command = new SqlCommand("SELECT " +
"[Job Name], " +
"[Job ID], " +
"[Package Count], " +
"[Ship Method] " +
"FROM [cjs_data] " +
"WHERE [File Name] LIKE '%FDY%' AND [JOB ID] = #jobID", conn);
command.Parameters.Add("#jobID", SqlDbType.VarChar);
command.Parameters["#jobID"].Value = jobID;
//restructure to assign search results to string to later assign to model, as we will search again for SLA in a different database
using (reader = command.ExecuteReader()) {
if (reader.HasRows) {
while (reader.Read()) {
fidelityInfo = new FidelityModel();
fidelityInfo.cjsJobName = reader.GetString(0);
fidelityInfo.ipwNumber = reader.GetString(1);
fidelityInfo.packageCount = reader.GetInt32(2);
if (fidelityInfo.cjsJobName.Contains("OVN")) { fidelityInfo.overnight = "Yes"; } else {
fidelityInfo.overnight = (reader.GetString(3).Equals("Overnight")) ? "Yes" : "No";
}
//site = (cjsJobName.Contains("EDG")) ? "EDGEWOOD" : "Other Site"; //not always the case
fidelityInfo.site = "EDGEWOOD";
models.Add(fidelityInfo);
}
}
}
}
//How to incorporate this following block of code into the same model?
using (conn = new SqlConnection(#"server = [servername]; database = MustMail; Integrated Security = true;")) {
conn.Open();
command = new SqlCommand("SELECT [SLA] FROM [Job] WHERE [JobID] = #jobID", conn);
command.Parameters.Add("#jobID", SqlDbType.VarChar);
command.Parameters["#jobID"].Value = jobID;
using (reader = command.ExecuteReader()) {
if (reader.HasRows) {
while (reader.Read()) {
//fidelityInfo.sla = reader.GetDateTime(0);
}
}
}
}
return models;
}
As you can see right now I just have it working without fetching the SLA because I have no idea how to actually add the result I am fetching from the second database to the same model.
For each row in the DataReader create a new FidelityModel and add it to the list. Something like:
while (reader.Read())
{
var m = new FidelityModel()
{
cjsJobName = reader.GetString(0),
ipwNumber = reader.GetString(1),
packageCount = reader.GetInt32(2),
sla = DateTime.Now
};
if (m.cjsJobName.Contains("OVN"))
{
m.overnight = "Yes";
}
else
{
m.overnight = (reader.GetString(3).Equals("Overnight")) ? "Yes" : "No";
}
models.Add(m);
}
I tried to make an e-contact app with C# on Visual Studio 2019 connected to a Miscrosoft SQL database (local) following a youtube tutorial.
The app is not complete yet, anyway the btnAdd should work, but it doesn't add the user and the return of the method (Insert).
It always returns false - Can anyone help me?
private void BntAdd_Click(object sender, EventArgs e) {
//Get the value from the imput fields
c.Nome = txtBoxName.Text;
c.Cognome = txtBoxSurname.Text;
c.Telefono1= txtBoxPhone1.Text;
c.Telefono = txtBoxPhone.Text;
c.Email = txtBoxEmail.Text;
//Inserting Data into Database uing the method we created is previous episode
bool success = c.Insert(c);
if (success == true)
{
//Successfully Inserted
MessageBox.Show("New contact added!");
//Call the clear Method Here
Clear();
}
else
{
//Failed to add Contact
MessageBox.Show("ERROR!)");
}
//load Data on Data GRidview
DataTable dt = c.Select();
dgvRubrica.DataSource = dt;
}
public void Clear()
{
txtBoxName.Text = "";
txtBoxSurname.Text = "";
txtBoxPhone1.Text = "";
txtBoxPhone.Text = "";
txtBoxEmail.Text = "";
}
public bool Insert (rubricaClass c) {
bool isSuccess = false;
SqlConnection conn = new SqlConnection(myconnstrng);
try
{
string sql = "INSERT INTO tbl_Rubrica (Nome, Cognome, Telefono1, Telefono, Email) VALUES (#Nome, #Cognome, #Telefono1, #Telefono, #Email)";
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.AddWithValue("#Nome", c.Nome);
cmd.Parameters.AddWithValue("#Cognome", c.Cognome);
cmd.Parameters.AddWithValue("#Telefono1", c.Telefono1);
cmd.Parameters.AddWithValue("#Telefono", c.Telefono);
cmd.Parameters.AddWithValue("#Email", c.Email);
conn.Open();
int rows = cmd.ExecuteNonQuery();
if (rows > 0)
{
isSuccess = true;
}
else
{
isSuccess = false;
}
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
return isSuccess;
}
It doesn't give any errors, it work but when i type the ata into txtBoxes and then i press the add button it says Error (message box inserte in the else)
Step 1 is to remove the catch-all exception handling from the Insert method. Most of the ADO.NET database classes implement IDisposable, so you just need a using(...) block to make sure the command is disposed automatically (which will also close and dispose the connection instance):
public bool Insert (rubricaClass c)
{
bool isSuccess = false;
SqlConnection conn = new SqlConnection(myconnstrng);
string sql = "INSERT INTO tbl_Rubrica (Nome, Cognome, Telefono1, Telefono, Email) VALUES (#Nome, #Cognome, #Telefono1, #Telefono, #Email)";
using(SqlCommand cmd = new SqlCommand(sql, conn))
{
cmd.Parameters.AddWithValue("#Nome", c.Nome);
cmd.Parameters.AddWithValue("#Cognome", c.Cognome);
cmd.Parameters.AddWithValue("#Telefono1", c.Telefono1);
cmd.Parameters.AddWithValue("#Telefono", c.Telefono);
cmd.Parameters.AddWithValue("#Email", c.Email);
conn.Open();
int rows = cmd.ExecuteNonQuery();
if (rows > 0)
{
isSuccess = true;
}
else
{
isSuccess = false;
}
}
return isSuccess;
}
Once that's squared away, Step 2 is to move your exception handling into the application. I don't recommend this "catch everything"-style code, but it works for now, I suppose:
private void BntAdd_Click(object sender, EventArgs e)
{
//Get the value from the imput fields
c.Nome = txtBoxName.Text;
c.Cognome = txtBoxSurname.Text;
c.Telefono1= txtBoxPhone1.Text;
c.Telefono = txtBoxPhone.Text;
c.Email = txtBoxEmail.Text;
try
{
//Inserting Data into Database uing the method we created is previous episode
bool success = c.Insert(c);
if (success == true)
{
//Successfully Inserted
MessageBox.Show("New contact added!");
//Call the clear Method Here
Clear();
}
else
{
//Failed to add Contact
MessageBox.Show("ERROR!)");
}
//load Data on Data GRidview
DataTable dt = c.Select();
dgvRubrica.DataSource = dt;
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
This will likely tell you that you either have an error in your SQL syntax, or that the command itself could not be run (i.e. the connection string is invalid or the server can't be reached).
I am opening a data reader within another one, but when I open the second data reader and try to read the data, it says that it is closed even though I just opened it.
Here is my function:
protected void checkBookStockAgain()
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["ConnectionStore"].ConnectionString);
conn.Open();
string selectCartString = "Select Item, Price, Quantity From ShoppingCart Where Username = #User";
SqlCommand cmd = new SqlCommand(selectCartString, conn);
cmd.Parameters.AddWithValue("#User", Session["user"].ToString());
SqlDataReader readCart = cmd.ExecuteReader();
while (readCart.Read())
{
string selectBookInfo = "Select Quantity from BookInfo where Title = #Title";
SqlCommand bookInfoQuantitycmd = new SqlCommand(selectBookInfo, conn);
bookInfoQuantitycmd.Parameters.AddWithValue("#Title", readCart["Item"]);
SqlDataReader quantityReader = bookInfoQuantitycmd.ExecuteReader();
while (quantityReader.Read())
{
if (Convert.ToInt32(readCart["Quantity"]) > Convert.ToInt32(quantityReader["Quantity"]))
{
updateCart = false;
quantityReader.Close();
readCart.Close();
conn.Close();
}
else if (Convert.ToInt32(readCart["Quantity"]) < Convert.ToInt32(quantityReader["Quantity"]))
{
updateCart = true;
invQuantity = Convert.ToInt32(quantityReader["Quantity"].ToString()) - Convert.ToInt32(readCart["Quantity"].ToString());
quantityReader.Close();
readCart.Close();
conn.Close();
}
else if (Convert.ToInt32(readCart["Quantity"]) == Convert.ToInt32(quantityReader["Quantity"]))
{
updateCart = true;
removeBookFromStore(readCart);
quantityReader.Close();
readCart.Close();
conn.Close();
}
else
{
quantityReader.Close();
readCart.Close();
conn.Close();
}
}
}
}
The error given states "Invalid attempt to call Read when reader is closed" and the error occurs when trying to run the while loop through quantityReader. As a side note, I've enabled MARS (Multiple Active Results Sets) in my connection string.
I created a custom login page using Forms Authentication and using a sQL DB to store user data. I am able to create a session variable from the username, but wondering if it is possible to pull a separate field and create a session variable based on that. I would like the session variable to be based off a SalesNumber a 5 digit decimal field. Please give me any comments or suggestions.
cmd = new SqlCommand("Select pwd,SalesNumber from users where uname=#userName", conn);
cmd.Parameters.Add("#userName", System.Data.SqlDbType.VarChar, 25);
cmd.Parameters["#userName"].Value = userName;
Session["userName"] = userName;
Thanks....
Also keep in mind you can store an entire object in the session instead of seperate variables:
UserObject user = DAL.GetUserObject(userName);
Session["CurrentUser"] = user;
// Later...
UserObject user = Session["CurrentUser"] as UserObject;
// ...
To add on, you could wrap it in a nice property:
private UserObject CurrentUser
{
get
{
return this.Session["CurrentUser"] as UserObject;
}
set
{
this.Session["CurrentUser"] = value;
}
}
When you get the SalesNumber from your database query, just use
Session["SalesNumber"] = <the value of the SalesNumber column from the query>
Or is there something else I'm missing in the question...?
in your DAL just create your Login sequence like:
public bool LoginUser(String username, String password)
{
bool r = false;
using (SqlConnection cn = new SqlConnection(ConfigurationManager.ConnectionStrings["DBConn"].ConnectionString))
{
using(SqlCommand cm = new SqlCommand())
{
cm.Connection = cn;
cm.CommandType = CommandType.Text;
cm.CommandText = "SELECT Name, SalesNumber FROM users WHERE uname = #username AND pwd = #password;";
cm.Parameters.AddWithValue("#username", username);
cm.Parameters.AddWithValue("#password", password);
cn.Open();
SqlDataReader dr = cm.ExecuteReader();
if (dr.HasRows)
{
// user exists
HttpContext.Current.Session["SalesNumber"] = dr["SalesNumber"].ToString();
HttpContext.Current.Session["Username"] = username;
HttpContext.Current.Session["Name"] = dr["Name"].ToString();
r = true;
}
else
{
// Clear all sessions
HttpContext.Current.Session["SalesNumber"] = "";
HttpContext.Current.Session["Username"] = "";
HttpContext.Current.Session["Name"] = "";
}
}
}
return r;
}
from your code, in the login button click event just add
if (dalLogin.LoginUser(TextBoxUsername.Text.Trim(), TextBoxPassword.text.Trim()))
{
// User logged in sucessfuly
// all sessions are available
Response.Redirect("homepage.aspx");
}
else
{
// Username and password did not match! show error
}