Using Parameters.AddWithValue to pass database name fails - c#

I've been trying to perform a login query. I think my main problem with this function is the Parameters.AddWithValue portion, but don't really understand what is wrong.
Following code returns an error when ran:
Must declare the table variable "#database"
Code:
public static bool clsFuncLogin(string USER, string PASS,
string conStr, string strDatabase)
{
SqlConnection conn = new SqlConnection(
ConfigurationManager.ConnectionStrings[conStr].ConnectionString);
conn.Open();
using (SqlCommand StrQuer =
new SqlCommand("SELECT COUNT(*) FROM #database "+
"WHERE Username = #userid AND Password = #password", conn))
{
StrQuer.Parameters.AddWithValue("#userid", USER);
StrQuer.Parameters.AddWithValue("#password", PASS);
StrQuer.Parameters.AddWithValue("#database", strDatabase);
int DataQuery = Convert.ToInt32(StrQuer.ExecuteScalar().ToString());
if (DataQuery == 1)
{
System.Web.HttpContext.Current.Session["User"] = USER;
System.Web.HttpContext.Current.Session["Pass"] = PASS;
System.Web.HttpContext.Current.Session["loggedIn"] = "True";
return true;
}
else if (DataQuery > 1)
{
//to tell if a double is created in the db
//probably to be removed
System.Web.HttpContext.Current.Session["Double"] = USER;
return false;
}
else
{
return false;
}
}
}
Ive also done the query as
"SELECT COUNT(*) FROM" + strDatabase + " WHERE Username = " + USER +
" AND Password = " + PASS;
but I was told that that is bad practice. Any advice?

I've never seen table names passed as a parameter, and based on other posts (this and this for example), I don't think it can be easily done... at least, not via SqlCommand.Parameters.
It sounds like there's only two tables - admins and regular users. As an alternative, you could just pass a bool to the method, like isAdmin, then have two queries based on whether the user is an admin or a regular user.
public static bool clsFuncLogin(string user, string pass, string conStr, bool isAdmin)
{
...
var query = isAdmin
? "SELECT COUNT(*) FROM ADMIN_TABLE WHERE Username = #userid AND Password = #password"
: "SELECT COUNT(*) FROM REGULAR_TABLE WHERE Username = #userid AND Password = #password";
using (var sqlCommand = new SqlCommand(query, conn))
{
sqlCommand.Parameters.AddWithValue("#userid", user);
sqlCommand.Parameters.AddWithValue("#password", pass);
...
...

Main reason to use
SELECT * FROM TABLE WHERE column=#column
with parameters is to avoid all complications of providing correct formatting for the value. it is even more important if values are supplied as free text by user of your application since you will open all possibilities with SQL injection attacks if you fail to properly address all formatting issues (which is basically not worth the effort given solution with parameters).
I really hope that you don't allow users to supply table name and it's supplied by your own code, so you can quite safely use
var query = String.Format("SELECT * FROM {0} WHERE column=#column", tableName);
However I would just recommend to create two separate queries instead to properly separate concerns.

Related

how to check if a user input is stored in a sqlite database

i am making a c# application that allows for user to register and login so far i have managed to get the registering portion done but i am stuck with the login portion
i have a method called ExecuteQuery which queries through the sqlite file that stores the user information and i am not sure how to check if the datastored in the database matches with the username and password the user enterd
this is the portion that is ment to check for the correct username and password this is the part i am stuck with
if (File.Exists("Users.sqlite"))
{
string txtQuery = "select * from UserInfo where UserName ='"+ username + "' and Password ='" + password + "'";
mainClass.ExecuteQuery(txtQuery);
}
this is my method that queries through the database
public void ExecuteQuery(string txtQuery)
{
SetConnection();
sql_con.Open();
sql_cmd = sql_con.CreateCommand();
sql_cmd.CommandText = txtQuery;
sql_cmd.ExecuteNonQuery();
sql_con.Close();
}
the problem is that i am not sure how to check if the user input and the user details stored in the sqlite database match. the name of my sqlite database is Users andthe name of the table is UserInfo
You Execute Non Query, Execute non query not returning any data, it just executes the query, you use it in update, insert, delete, ETC ..
To Return results from your query, Use ExecuteQuery instead of ExecuteNonQuery. and save the results in a variable then return it.
Example:
public string ExecuteQuery(string txtQuery)
{
SetConnection();
sql_con.Open();
var sql_cmd = sql_con.CreateCommand();
sql_cmd.CommandText = txtQuery;
var x = sql_cmd.ExecuteQuery();
sql_con.Close();
return x;
}
and in the main page:
var result = mainClass.ExecuteQuery(txtQuery);
Result will include your query, which in your case will be the user info if exists.
Please don't forget to mark it as an answer and vote. hope that I have helped you.

Retrieving user password from DB

I have a table that has a list of user names and passwords and I want to match the the user name and password the user enter with the one saved in the DB. The code I am using only retrieves the login information of the first record in the users table, how can I change that so the code would work for all user.
I am a beginners at VS and I am trying to learn the basics so later on I will be implementing more complex login page with encryption.. Thank you
private void btnLogin_Click(object sender, EventArgs e)
{
SqlConnection cn = new SqlConnection();
SqlCommand cmd = new SqlCommand();
SqlDataReader dr;
cn.ConnectionString = "Server=;Database=;User Id=naljalid;Password=";
cmd.Connection = cn;
string username = tbxUserName.Text;
cmd.CommandText = "SELECT UserPassword FROM tblLoginProject WHERE UserName=username";
// open a connection to DB
cn.Open();
//read the table
dr = cmd.ExecuteReader();
//read a record from te data reader
dr.Read();
// compare the passwords
if (tbxPassword.Text == dr.GetString(0))
{
MessageBox.Show("Hello");
}
else
{
MessageBox.Show("Login failed, please re-enter your password");
}
}
The key to this is the SQL query, specifically the WHERE clause:
SELECT UserPassword FROM tblLoginProject
This query will return all the passwords from the database. But you want to retrieve the password of only one user, so you need to implement a WHERE clause
SELECT UserPassword FROM tblLoginProject WHERE UserName = #username
This query will retrieve the password for only a certain user where the value of the field UserName equals the value passed in the parameter #username. So now we need to make sure to pass that value. You can't just include it in the SQL query like you're doing right now. We do it like this:
cmd.Paramateres.AddWithValue("#username", username);
This should work fine, but for best practices you should check for both username and password at the same time:
SELECT count(*) FROM tblLoginProject WHERE UserName = #username AND UserPassword = #password
Then of course we pass both values:
cmd.Paramateres.AddWithValue("#username", username);
cmd.Paramateres.AddWithValue("#password", password);
This will return 0 if no users are found with that combination of username and password (invalid login), or more than 0 if such a user was found (valid login).
Next stop you should research hashing passwords. After that would be salting these hashes. Good luck!
Change the query a tidge to this:
cmd.CommandText = "SELECT UserPassword FROM tblLoginProject WHERE UserName = #username";
and then set that parameter value:
cmd.Parameters.AddWithValue("#username", tbxUserName.Text);
That will get you the row for the user you're looking for. Now on to a few more recommendations. The ADO.NET classes implement the IDispoable interface. That interface identifies that the class uses some unmanaged resources. You want to make sure those get disposed. Consider the following rewrite of your current code:
using (SqlConnection cn = new SqlConnection("Server=;Database=;User Id=naljalid;Password="))
using (SqlCommand cmd = new SqlCommand("SELECT UserName FROM tblLoginProject WHERE UserName = #username AND Password = #password", cn))
{
cn.Open();
cmd.Parameters.AddWithValue("#username", tbxUserName.Text);
cmd.Parameters.AddWithValue("#password", tbxPassword.Text);
var result = cmd.ExecuteScalar() as string;
if (string.IsNullOrEmpty(result))
{
// user was not found
}
else
{
// user was found
}
}
It leverages the using statement to ensure that the objects get disposed.

Check if record in a table exist in a database through ExecuteNonQuery

in my program i need to check if a record in the database already exists in the table using the if statement.
using c# i am trying to do this through an sql connection.
as i supposed that the ExecuteNonQuery(); command returns an integer value, if my supposing is true, i want to know what value is true to know that a certain record exists in the table or not. here's a sample of my code:
using (SqlConnection sqlConnection = dbUtil.GetSqlConnection(dbUtil.GetConnectionStringByName("NonConnectionString")))
{
using (SqlCommand sqlCommand = new SqlCommand("SELECT * from users where user_name like 'Adam' AND password like '123456'", sqlConnection))
{
sqlresult = sqlCommand.ExecuteNonQuery();
}
}
considering sqlresult has been initialized previously in the main as int sqlresult;
so i would like to know, that if this user 'Adam' exists in the database or not. and if he exists, then i want to proceed with an 'if' statement saying for example:
if(sqlresult == 0)
{
MessageBox.Show("Adam exists!");
}
so i just don't know the integer that it should return, and i am either not sure that this is the proper way to do it so.
thank you.
If you want to check if the user exists, you have to change your sql and use COUNT or EXISTS:
So instead of
SELECT * from users where user_name like 'Adam' AND password like '123456'
this
SELECT COUNT(*) from users where user_name like 'Adam' AND password like '123456'
Now you can use ExecuteScalar to retrieve the count of users with this username and password:
int userCount = (int) sqlCommand.ExecuteScalar();
if(userCount > 0)
// user exists ....
Note that you should use sql-parameters to prevent sql-injection:
using (SqlCommand sqlCommand = new SqlCommand("SELECT COUNT(*) from users where user_name like #username AND password like #password", sqlConnection))
{
sqlConnection.Open();
sqlCommand.Parameters.AddWithValue("#username", userName);
sqlCommand.Parameters.AddWithValue("#password", passWord);
int userCount = (int) sqlCommand.ExecuteScalar();
...
}
You should be using ExecuteScalar for cheking if the record exists. ExecuteNonQuery runs a transact-SQL statement against the connection and returns the number of rows affected for an UPDATE, INSERT, or DELETE. It doesn't apply for SELECT statements
I would use Select Top 1 Id rather than the count(*) because it can be much faster
You should do a count(1) on the table instead of a select * and then executescalar to get that integer value.
Using your existing code I would change it to be:
using (SqlConnection sqlConnection = dbUtil.GetSqlConnection(dbUtil.GetConnectionStringByName("NonConnectionString")))
{
using (SqlCommand sqlCommand = new SqlCommand("SELECT count(1) from users where user_name = 'Adam' AND password = '123456'", sqlConnection))
{
sqlresult = sqlCommand.ExecuteNonQuery();
}
}
Please note that I have used equals values instead of like values.
Also if I were do to this I would change your inline sql to use a stored procedure.
If someday you want to use EF just do:
private MyDb db = new MyDb();
public bool UserExists(string userName, string password){
return db.Users.Any(x => x.user_name.Equals(userName, StringComparison.InvariantCultureIgnoreCase)
&& x.password.Equals(password, StringComparison.InvariantCultureIgnoreCase));
}
Or do a generic method, so you can handle multiple entites:
public bool EntityExists<T>(Expression<Func<T, bool>> predicate) where T : class, new()
{
return db.Set<T>().Any(predicate);
}
Usage:
EntityExists<Users>(x => x.user_name.Equals(userName, StringComparison.InvariantCultureIgnoreCase)
&& x.password.Equals(password, StringComparison.InvariantCultureIgnoreCase));

Updating MySql counter when users log in

I have a website where users can log in. The client wants there to be a way to record the number of times any particular user logs in. I have a "Counter" row in the table. How do I program the app (built in C# ASP.NET) to update the counter when people log in? Is this code correct:
cmd.ExecuteNonQuery = "UPDATE Counter FROM brokercenter"
I just recently graduated (as in the 10th of this month) so I am new to this, plus I know nothing about databases, I am just learning on the job. Please let me know if I need any other parameter or connection string or aything else? This is in the button click event and there is already a connection string there to check the username and password so I don't think I need another connection string, but I don;t know for sure. Thanks in advance!
For that matter, here is the whole event (the login stuff works fine, just the update is my question):
string connectionString =
ConfigurationManager.ConnectionStrings["moverschoiceConnectionString"].ConnectionString;
OdbcConnection conn = new OdbcConnection(connectionString);
conn.Open(); OdbcCommand cmd = new OdbcCommand();
cmd.Connection = conn;
cmd.CommandText = "select Email, Password from brokercenter where Email = '" + txtLoginEmail.Text + "'";
OdbcDataReader reader = cmd.ExecuteReader();
while(reader.Read())
{
if (reader["Password"].ToString() == txtLoginPassword.Text)
{
reader.Close();
if (cbRememberMe.Checked == true)
{
Response.Cookies["username"].Value = txtLoginEmail.Text;
Response.Cookies["username"].Expires = DateTime.Now.AddMonths(1);
Response.Cookies["password"].Value = txtLoginPassword.Text;
Response.Cookies["password"].Expires = DateTime.Now.AddMonths(1);
}
else
{
Response.Cookies["username"].Expires = DateTime.Now.AddMonths(-1);
Response.Cookies["password"].Expires = DateTime.Now.AddMonths(-1);
}
Response.Redirect("BrokerResources.aspx");
}
else
{
lblLoginError.Text = "Invalid Password";
}
}
lblLoginError.Text = "Invalid Email or Password";
reader.Close();
cmd.ExecuteNonQuery = "UPDATE counter FROM brokercenter";
}
For a start, you should read about using UPDATE in MySQL's Reference Manual.
There is even an example for exactly what you want to do.
Quote from the link:
If you access a column from the table to be updated in an expression,
UPDATE uses the current value of the column. For example, the
following statement sets col1 to one more than its current value:
UPDATE t1 SET col1 = col1 + 1;
This is basically all you need, you just need to add a WHERE clause and filter for the username or for the email.
Plus, you should read about SQL Injection because of this:
where Email = '" + txtLoginEmail.Text + "'";
Concatenating strings like this to pass parameters can cause problems as described in the link.
Here's an example how to do it better.
cmd.ExecuteNonQuery = String.Format("UPDATE brokercenter SET counter = {0} WHERE Email = {1}", myCounter++, txtLoginEmail.Text);
where "myCounter" is a local counter variable (which should also be read from the database). Does this make sense now?

Exception while inserting values in to SQL table through C#

HI i had manullay created textbox's and then used it for creating a new user. I am using SQL SERVER 2005 for backend and Visual Server 2008 for front..
I have this LoginAccount table which stores details of the new user created. When i Click the button(in which i have written code to create a new user through SQL insert),
string strConnection = ConfigurationManager.ConnectionStrings"FHDLConnectionString"].ToString();
SqlConnection sqlConnection = new SqlConnection(strConnection);
string username = TextBox1.Text;
string password = TextBox2.Text;
string confirmpass = TextBox3.Text;
string SQLQuery = "Select username From LoginAccount where '" + username + "'";
string SQLQuery1 = "Insert into LoginAccount values ('" + username + "','" + password + "')";
SqlCommand command = new SqlCommand(SQLQuery, sqlConnection);
SqlCommand command1 = new SqlCommand(SQLQuery1, sqlConnection);
sqlConnection.Open();
string CheckUsername = "";
if (password.ToString() != confirmpass.ToString())
{
Literal1.Text = " Password's does not match ";
}
else
{
try
{
CheckUsername = command.ExecuteScalar().ToString();
}
catch (Exception er)
{
Literal1.Text = " Username already exists ";
}
string insertQuery = "";
try
{
insertQuery = command1.ExecuteScalar().ToString();
Server.Transfer("Login_Created.aspx");
}
catch (Exception er)
{
Literal1.Text = " Could not create the user, Please retry with some other option ";
}
}
sqlConnection.Close();
I am getting these exception's
An expression of non-boolean type specified in a context where a condition is expected, near 'fhdl'
This error i got at the first catch
and
Object reference not set to an instance of an object.
This for at the last catch.
But the main thing is i am able to insert the username and password into the LoginAccount table!!!!!!! i.e. when i saw the table contents i could see the new user created in that table.
The other thing is This code executed perfectly once before but not now :(
Please could anyone tell me where am i going wrong?
I am new to C# with SQl ...
1 - ExecuteScalar() means that there's a return value. The insert doesn't have a return value. Use ExecuteNonQuery instead.
2 - Also, for the insert statement, specify the fields you're inserting into. Without specifying the fields, it's trying to insert into the first two columns of the table, which may not be username and password.
insert into LoginAccount(UserName, Password) values ....
3 - your select statement is incorrect.
select from LoginAccount where UserName='... You're missing the field name.
Three things:
Your first query doesn't do what you want it to. It resolves to:
Select username From LoginAccount where 'username'
You want to check the username against the database.
This code leaves you wide open to SQL Injection attacks. See this article for how to prevent them in C#.
On a similar note, you really don't want to store passwords in the clear in your database either.

Categories

Resources