When 'login' button is clicked I would like to iterate through a column in a table and check if a match occurs. How would I go about doing this?
I have connected through to a database and I'm reading from database and writing to database fine. I am not sure how I would iterate through a database.
P.S I'm new to both c# and visual studios. I am not having much trouble with C#, since I come over from Java however I'm struggling to get into grips with Visual studios.
This is simple you'll see.
SqlConnection myConnection = new SqlConnection(#"Server = (Local); Integrated Security = True;" + "Database = insertDataBaseName"); // Assuming (Local)
myConnection.Open();
SqlCommand myCommand = myConnection.CreateCommand();
myCommand.CommandText = ("SELECT UserName, Password,from Login"); // Where Login is your table . UserName and Password Columns
SqlDataReader myReader = myCommand.ExecuteReader();
bool login = false;
while (myReader.Read())
{
if (userNameBox.Text.CompareTo(myReader["UserName"].ToString()) == 0 && passwordBox.Text.CompareTo(myReader["Password"].ToString()) == 0) // A little messy but does the job to compare your infos assuming your using a textbox for username and password
{
login = true;
}
}
if (login)
{
//Your're in.
}
else
{
MessageBox.Show("Invalid UserName or Password", "Access Denied"); // Error message
}
myReader.Close();
myConnection.Close(); // Just close everything
Hope this helps.
Dont hesitate if you have any question on this code part.
in sql something like this will help
Select top(1) from Users where Id = #Id
or in linq
var user = (from u in users
where u.Id == id
select u).SingleOrDefault();
If you are chekcing for a username password validation, I think you should not get all user records and loop Iterate thru that. What if you get 100000 user registrations ? You really want to iterate 100000 times ? Really ?
You should probably query for the purticular record you are looking for
Some thing like this
SELECT TOP 1 UserID,FIRSTNAME,LASTNAME,HASHED_PASSWORD,SALT WHERE USERNAME='kristy'
Execute that query againinst your database and see whether you have any records exist, If you have one record present, now you can validate the password with the data you have.
Related
In this situation, there is a form used for updating user information (username, password, mobile number, etc.).
Below is the code I used to check if the username exists in the database:
string sql = "SELECT username FROM (SELECT username FROM useraccount WHERE username != #old_uname)ua WHERE BINARY username = #new_uname LIMIT 1;";
MySqlCommand cmd = new MySqlCommand(sql, SecurityMod.dbconn());
cmd.Parameters.AddWithValue("#old_uname", old_uname);
cmd.Parameters.AddWithValue("#new_uname", new_uname);
if (cmd.ExecuteScalar() == null)
{
isValidNewUname = true;
}
It works if the user really changes his/her username. But the problem occurs when the user made changes to anything but the username field. The isValidNewUname variable remains false. Any ideas and suggestions would be a big help.
Instead of basing on fetched username, I opted instead for the uid. I solved the problem with the following code:
string sql = "SELECT uid FROM useraccount WHERE BINARY username = #new_uname;";
MySqlCommand cmd = new MySqlCommand(sql, SecurityMod.dbconn());
cmd.Parameters.AddWithValue("#new_uname", new_uname);
if (cmd.ExecuteScalar() == null || cmd.ExecuteScalar().ToString() == userID)
{
isValidNewUname = true;
}
This code is shorter and more simple hence easier to maintain. What happens here is that the query looks for the uid of the #new_uname in the database. It then compares the fetched uid to the uid of the current user. If it is the same, it means that the fetched result of the query is simply the user itself, so it doesn't really matter if their the same or not since it belongs to only one user. If the fetched uid is not equal to the uid of the current user, it means the username input by the user is already taken so isValidNewUname would be false. If the query above doesn't return results, then the #new_uname is available since it doesn't have a record in the database.
I am working on a login page. I'd like to check if the username & password exists in the database. I have three database tables : Teams,Organizers,Admins with username & password field in each table respectively. I am implementing the login in three-tier architecture.
I believe that I have a problem with my SQL statement below. I tested my sql query with a distinct/valid team username and team password. The COUNT query returns more than one row, which is incorrect.
This are my codes for the data access layer :
public int getExistingAccount(string username, string password)
{
string queryStr = "SELECT COUNT(*) FROM Teams t,Organizers o,Admins a WHERE (t.teamUsername=#username AND t.teamPassword=#password) OR (o.organizerUsername=#username AND o.organizerPassword=#password) OR (a.adminUsername=#username AND a.adminPassword=#password)";
SqlConnection conn = new SqlConnection(_connStr);
SqlCommand cmd = new SqlCommand(queryStr, conn);
cmd.Parameters.AddWithValue("#username", username);
cmd.Parameters.AddWithValue("#password", password);
int returnValue = 0;
conn.Open();
returnValue = (int)cmd.ExecuteScalar();
conn.Close();
return returnValue;
}
As for the business logic layer codes :
public string getAccount(string username, string password)
{
string returnMessage = "";
if (username.Length == 0)
returnMessage += "Username cannot empty</br>";
if (password.Length == 0)
returnMessage += "Password cannot be empty</br>";
if (username.Equals(password))
{
returnMessage += "Duplicate value. Please try again</br>";
}
//Invoke validateInput() method to validate data
if (returnMessage.Length == 0)
{
int noOfRows = 0;
LogAccounts logInd = new LogAccounts();
noOfRows = logInd.getExistingAccount(username, password);
if (noOfRows > 0)
returnMessage += "Account found";
else
returnMessage += "Invalid username/password.";
}
return returnMessage;
}
Try this, select from each table and UNION ALL the results, then count the rows.
select count(*) from
(
SELECT 1 as dummyname FROM Teams t
WHERE (t.teamUsername=#username AND t.teamPassword=#password)
union all
SELECT 1 FROM Organizers o
WHERE (o.organizerUsername=#username AND o.organizerPassword=#password)
UNION ALL
select 1 from Admnis
WHERE (a.adminUsername=#username AND a.adminPassword=#password)
)
I seems you have a really awkward database design, where fetching a single user requires a unnaturally large/long sql query.
In almost every use case you would have a single Users table, and if you need to tie the user to some additional information, you would have a reference to the user table by the UserId. You should read up on foreign keys aswell.
Quick sample:
Users:
- UserId (int or guid) (primary key)
- .... (additional fields removed for brewity)
The other tables would refer to the UserId column, and use that to pull information about the user with a join.
E.g.: SELECT T.*, U.* FROM Teams T INNER JOIN Users U ON U.UserId = T.UserId WHERE U.Username = "AwesomeCoach";
A simple validate query would be something like this:
SELECT COUNT(*) FROM Users WHERE Username = xx AND Password = xx
That would return an integer that specifies how many rows that matched the given username/password combination. It should be either 1 or 0. Put a Unique contraint on the Username column to ensure that there are only one occurence of each Username.
Footnote: I see that you have got an answer that solves the problem you were facing, but I would recommend that you read up on some database design, and try to keep it as simple as possible. Managing multiple users across multiple tables can and will be a hassle as the application grows.
Your design is really bad, you should have all users in one table. After that if you want to take user by id, you should check 3 diff tables. Anyway the problem is in the query you should write it like this:
string queryStr = #"
SELECT
COUNT(*) AS TeamsCount,
(SELECT COUNT(*) Organizers WHERE organizerUsername=#username AND organizerPassword=#password) AS OrgCount,
(SELECT Count(*) Admins WHERE adminUsername=#username AND adminPassword=#password) AS AdminCount
FROM
Teams
WHERE
teamUsername=#username AND
teamPassword=#password";
The query should look something like this. After that you need to return this in DataSet. You need:
DataSet dst = new DataSet();
using(SqlAdapter adapter = new SqlAdapter(cmd))
{
adapter.Fill(dst);
}
In this case you will have dst with 3 columns in it. Check for existing user should be:
if(dst.Tables[0].Rows[0]["TeamsCount"] > 0 ||
dst.Tables[0].Rows[0]["OrgCount"] > 0 ||
dst.Tables[0].Rows[0]["AdminCount"] > 0)
{
//user already exist !
}
I made a login form for an application, and I want to check if the login data from the user exists in the database so that he can log in successfully or display an message telling him that his login details are wrong.
I tried the OleDbDataReader but that didn't work, so I added a username and password in my database (in the table Etudiant) and tried to count the number of rows in the table Etudiant, so that the login succeeds if the count is greater than 0, otherwise "wrong details" is shown. But the problem is always the same, only the second message is shown.
Here's my code:
string strcnn = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=app.mdb";
OleDbConnection cnn = new OleDbConnection(strcnn);
cnn.Open();
string reqet = "SELECT count(*) FROM Etudiant";
OleDbCommand cmd = new OleDbCommand(reqet, cnn);
int x = (int)cmd.ExecuteScalar();
if (x>0)
MessageBox.Show("Bienvenu cher étudiant");
else
MessageBox.Show("Données invalides !");
cnn.Close();
You must check the username and password on your query or it will return the full table row count, someting like SELECT COUNT(*) FROM Etudiant WHERE User=(username) AND Password=(password).
What I am trying to do is grab the current logged in users username and compare that against a database which contains users, and also includes an Active flag and an Admin flag. I want to compare the current logged in user in the tbl_Person table and their respective user in the table to see if they are marked as Active and Admin. If both are true, they get access to an Admin page. I have the below so far which isn't working. Some of which I know why, some I don't. I think I am on the right track, that being said I am sure I am not doing it correctly. I know you use ExecuteScalar() to return something along with OUTPUT in the query string but couldn't get that to work. The other glaring issue is that I am trying to return integers when the username is a string and the active and admin flags are Bools. I know that I only have Active in there are the moment. I was trying to get that to work before adding in something else.
I read that with the ExecuteScalar, you could Parse and convert ToString, but that didn't work and I found evidence that this might not be the correct thing to do, but I'm really not sure.
I have got a few different errors. Type errors, invalid column when I've tried to do the OUTPUT. With OUTPUT I tried as just OUTPUT and because I know when returning after inserting, you do inserted.name. I tried selected.name as a hunch, but that didn't work.
I was thinking that if I pulled the info, concatenated them and then did a comparison, that this would do what I want, but I am open to other suggestions. Thanks.
string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["HSEProjRegConnectionString1"].ConnectionString);
conn.Open();
SqlCommand sqlUserName = new SqlCommand("SELECT [username] FROM [tbl_Person]", conn);
SqlCommand sqlActive = new SqlCommand("SELECT [active] FROM [tbl_Person]", conn);
int result1 = ((int)sqlUserName.ExecuteScalar());
int result2 = ((int)sqlActive.ExecuteScalar());
string userInfo = result1 + "." +result2;
string userName = userName + "." +result2;
if (userInfo == userName)
{
Woo, you have access.
}
else
{
Sorry, but no.
}
The Query isn't final either. Once it is working, I'll change it to a parameterised query.
Okay, consider the following code:
string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["HSEProjRegConnectionString1"].ConnectionString))
{
conn.Open();
using (SqlCommand cmd = new SqlCommand("SELECT [active] FROM [tbl_Person] WHERE username = #username", conn))
{
// since we can literally filter the results, if something comes back
// we know they are registered
cmd.Parameters.AddWithValue("#username", userName);
var res = cmd.ExecuteScalar();
bool registeredAndActive = (bool)res;
// unless of course `[active]` is an INT -then do this
bool registeredAndActive = (int)res == 1 ? true : false;
// but really -set [active] up as a BIT if it's not **and**
// please make it non-nullable :D
}
}
I'm pretty sure it does what you want. But it also shows you some best practices like:
Leverage the using statement for all IDisposable objects.
Filter the query as much as you can and make only one round trip.
while (reader.Read())
{
if (TextBox1.Text.CompareTo(reader["usernam"].ToString()) == 0&&TextBox2.Text.CompareTo(reader["passwd"].ToString()) == 0) // A little messy but does the job to compare your infos assuming your using a textbox for username and password
{
Label3.Text = "Redirecting";
Response.Cookies["dbname"]["Name"] = reader["usernam"].ToString();
Response.Cookies["dbname"].Expires = DateTime.Now.AddSeconds(10);
Response.Redirect("index2.aspx");
}
else
{ Label3.Text = "NO"; }
}
When i try to compare both username (usernam) and password (passwd) I get this error.
If i only compare the username with the db entries it works like a charm.
It will only give the error when actual data is used.
E.I. If i enter [admin], [admin] in the log in web page it will give me the error, if i enter [asd], [asd] then the label would change to NO.
The idea behind the code is a log in page.
I hope my explanation is good enough.
You are only selecting the username from your table. You are not selecting the password, hence it throws an exception when you try to retrieve it from the result set.
Change the query to this:
string selectString = "SELECT usernam, passwd FROM Table1";
You can also use * instead of column names in your query. Here its just a small scenario. If there are multiple columns then you just need to use * for that. That will make your query simple.