Checking if user exists in MySQL database fails - c#

Not sure why the following code gives me an exception. I'm trying to check if a username exists in a MySQL database, if not then I want to create a user. If I run either query by itself then it works ok but not together.
int valid = -1;
using (MySqlConnection cnn = new MySqlConnection(conString))
{
cnn.Open();
bool usernameExists = false;
string sql1 = String.Format("SELECT Username FROM Users WHERE Username = \"{0}\"", username);
MySqlCommand cmd1 = new MySqlCommand(sql1, cnn);
usernameExists = (int)cmd1.ExecuteScalar() > 0;
if (!usernameExists)
{
string sql = String.Format("INSERT INTO Users(Username, Password) VALUES(\"{0}\", \"{1}\")", username, password);
MySqlCommand cmd = new MySqlCommand(sql, cnn);
valid = cmd.ExecuteNonQuery();
}
}
return valid;

First, MySQL uses single quotes. This means your query would be:
string.format("SELECT Username FROM Users WHERE Username = '{0}' LIMIT 1", Username);
However, this is very vulnerable with SQL injection. Here's a code to use MySQL Parameters to prevent it.
int valid = -1;
using (MySqlConnection cnn = new MySqlConnection(conString))
{
cnn.Open();
bool usernameExists = false;
MySqlCommand cmd1 = new MySqlCommand("SELECT Username FROM Users WHERE Username = #username LIMIT 1", cnn);
cmd1.Parameters.AddWithValue("#username", username);
usernameExists = (int)cmd1.ExecuteScalar() > 0;
if (!usernameExists)
{
MySqlCommand cmd = new MySqlCommand("INSERT INTO Users(Username, Password) VALUES(#username, #password)", cnn);
cmd.Parameters.AddWithValue("#username", username);
cmd.Parameters.AddWithValue("#password", password);
valid = cmd.ExecuteNonQuery();
}
}
return valid;
Could you try this?

I got it working by changing the first query from:
MySqlCommand cmd1 = new MySqlCommand("SELECT Username FROM Users WHERE Username = #username LIMIT 1", cnn);
to
MySqlCommand cmd1 = new MySqlCommand("SELECT COUNT(UserID) FROM Users WHERE Username = #username", cnn);
int valid = int.Parse(cmd.ExecuteScalar().ToString());
Thanks for the help.

Related

C# ASP.NET Web Api Controller - Get all rows from a table using SqlCommand

I'm making a web api server that I need for a school project because we have to make several applications on different platforms to communicate through messages and the web api server has GET, POST and DELETE methods.
Right now I have a GET method that will return a row in a table using ID (for example http://localhost:1442/api/Users/1 will return User with ID of 1)
the code looks like this:
public User Get(int id)
{
SqlDataReader reader = null;
SqlConnection myConnection = new SqlConnection();
myConnection.ConnectionString = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=D:\Downloads\SERVER\SERVER\App_Data\dbCoffeeBreak_.mdf;Integrated Security=True";
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.CommandType = CommandType.Text;
sqlCmd.CommandText = "Select * from tbUsers where ID=" + id + "";
sqlCmd.Connection = myConnection;
myConnection.Open();
reader = sqlCmd.ExecuteReader();
User u = null;
while (reader.Read())
{
u = new User();
u.ID = Convert.ToInt32(reader.GetValue(0));
u.Login = reader.GetValue(1).ToString();
u.Password = reader.GetValue(2).ToString();
u.Avatar = reader.GetValue(3).ToString();
u.Email = reader.GetValue(4).ToString();
u.Online = Convert.ToBoolean(reader.GetValue(5));
}
myConnection.Close();
return u;
}
but I'm not sure how to make it so that by typing for example only http://localhost:1442/api/Users the server would return ALL columns in the table. I tried setting the sqlCmd.CommandText = to just Select * from tbUsers but that just returns the last User in the table not all of them.
That's because you are only returning the last user from Reader.Read
There are couple of issues and suggestions for you
1. Make Id as optional parameter , so that if you dont pass anyId, it will query for allusers`. With this you dont need to
create separate method for getting all users.
2. Return List<User> instead of return single User
public List<User> Get(int? id = null)
{
SqlDataReader reader = null;
SqlConnection myConnection = new SqlConnection();
myConnection.ConnectionString = #"Data Source=(LocalDB)\MSSQLLocalDB;AttachDbFilename=D:\Downloads\SERVER\SERVER\App_Data\dbCoffeeBreak_.mdf;Integrated Security=True";
SqlCommand sqlCmd = new SqlCommand();
sqlCmd.CommandType = CommandType.Text;
if(id !=null)
sqlCmd.CommandText = "Select * from tbUsers where ID=" + id + "";
else
sqlCmd.CommandText = "Select * from tbUsers ";
sqlCmd.Connection = myConnection;
myConnection.Open();
reader = sqlCmd.ExecuteReader();
List<User> users = List<User>();
while (reader.Read())
{
u = new User();
u.ID = Convert.ToInt32(reader.GetValue(0));
u.Login = reader.GetValue(1).ToString();
u.Password = reader.GetValue(2).ToString();
u.Avatar = reader.GetValue(3).ToString();
u.Email = reader.GetValue(4).ToString();
u.Online = Convert.ToBoolean(reader.GetValue(5));
users.Add(u);
}
myConnection.Close();
return users;
}
Plus always use Parameterized queries to prevent SQL Injection Attacks
Will suggest you to update your query as
sqlCmd.CommandText = "Select * from tbUsers where ID=#Id";
sqlCmd.Parameters.AddWithValue("#Id", id);

how do i get column value from sql server 2008?

i have table where have 5 columns :
i wrote the code like this :
String SQLQuery = "SELECT count(*) FROM aspnet_Users where Username=#uname AND Password = #pwd";
using(SqlConnection sqlConnection = new SqlConnection(strConnection))
using(SqlCommand command = new SqlCommand(SQLQuery, sqlConnection))
{
sqlConnection.Open();
command.Parameters.AddWithValue("#uname", Username);
command.Parameters.AddWithValue("#pwd", Password);
int result = Convert.ToInt32(command.ExecuteScalar());
boolReturnValue = (result > 0);
}
here few more extra information i needed,if above Username and password is correct,
what i need is : userid, and role column data
Why you aren't doing that instead ?
string SQLQuery = "SELECT UserId FROM aspnet_Users where Username=#uname AND Password = #pwd";
[...]
object result = command.ExecuteScalar();
if (result == null)
{
boolReturnValue = false;
}
else
{
long userId = Convert.ToInt64(result);
boolReturnValue = true;
}
String SQLQuery = "SELECT Top 1 UserId, role FROM aspnet_Users where Username=#uname AND Password = #pwd";
using(SqlConnection sqlConnection = new SqlConnection(strConnection))
using(SqlCommand command = new SqlCommand(SQLQuery, sqlConnection))
{
sqlConnection.Open();
command.Parameters.AddWithValue("#uname", Username);
command.Parameters.AddWithValue("#pwd", Password);
SqlDataReader Reader = null;
if (sqlConnection.State == ConnectionState.Closed || sqlConnection.State == ConnectionState.Broken)
sqlConnection.Open();
Reader = command.ExecuteReader();
if (Reader.Read())
{
int UserId = Convert.ToInt32(Reader["UserId"]);
string Role = Convert.ToString(Reader["role"]);
}
}
Why don't you just get the UserId instead of the Count(*) so your query should look like this :
SELECT UserId FROM aspnet_Users where Username=#uname AND Password = #pwd
Username should be unique so you shouldn't retrieve more than one row...you can add a Top 1 in case you have multiple same username with same password.
Try this Code
SELECT count(*),userid,role FROM aspnet_Users where Username=#uname AND Password = #pwd Group by userid,role

Check if username existed in SQLExpress

Error shows : ExecuteScalar: Connection property has not been
initialized and exists = (int)cmd.ExecuteScalar() > 0;
bool exists = false;
using (SqlCommand cmd = new SqlCommand("select * from [Users] where UserName = #UserName"))
{
cmd.Parameters.AddWithValue("UserName", tbUserName.Text);
exists = (int)cmd.ExecuteScalar() > 0;
}
if (exists)
{
lblUserName.Text = "This username has been used by another user.";
}
else
{
SqlConnection connection = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True");
SqlCommand cmd;
cmd = new SqlCommand("INSERT INTO Users (UserID,FName, LName, PhoneNo, Address, Email, UserName, Password, Points, Role) VALUES (#UserID,#FName, #LName, #PhoneNo, #Address, #Email, #UserName, #Password, #Points, #Role)");
try
{
cmd.Connection = connection;
cmd.Parameters.AddWithValue("#UserID", UserID);
cmd.Parameters.AddWithValue("#FName", tbFName.Text);
cmd.Parameters.AddWithValue("#LName", tbLName.Text);
cmd.Parameters.AddWithValue("#PhoneNo", tbPhoneNo.Text);
cmd.Parameters.AddWithValue("#Address", tbAddress.Text);
cmd.Parameters.AddWithValue("#Email", tbEmail.Text);
cmd.Parameters.AddWithValue("#UserName", tbUserName.Text);
cmd.Parameters.AddWithValue("#Password", tbPassword.Text);
cmd.Parameters.AddWithValue("#Points", Points);
cmd.Parameters.AddWithValue("#Role", Role);
connection.Open();
cmd.ExecuteNonQuery();
}
finally
{
connection.Close();
//session
Session["UserName"] = tbUserName.Text;
Session["UserID"] = ("SELECT * FROM Users WHERE UserID = 'UserID'");
Session["Points"] = ("SELECT * FROM Users WHERE Points = 'Points'");
//pop out then redirect
ClientScript.RegisterStartupScript(this.GetType(), "Success", "<script type='text/javascript'>alert('Thank you or signing up with us!');window.location='Home.aspx';</script>'");
}
}
What should be the correct way to declare the connection first because I tried to put it before but I'm having problems with the cmd.
SqlConnection connection = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True");
SqlCommand cmd;
bool exists = false;
using (SqlCommand cmd = new SqlCommand("select * from [Users] where UserName = #UserName"))
{
cmd.Parameters.AddWithValue("UserName", tbUserName.Text);
exists = (int)cmd.ExecuteScalar() > 0;
}
You need to assign the connection to the command in your last example
So within your using statement add:
cmd.Connection = connection;
Additionally you don't need:
SqlCommand cmd;
as the command is created within the context of that using statement.
It's also considered good practice to wrap the Connection context within a using statement to ensure the actual connection get's disposed / closed correctly.
Try this,
using (SqlConnection connection = new SqlConnection(#"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True"))
{
connection .Open();
SqlCommand cmd = new SqlCommand("select * from [Users] where UserName = #UserName", connection );
cmd.Parameters.AddWithValue("UserName", tbUserName.Text);
bool exists = (int)cmd.ExecuteScalar() > 0;
}
You didn't specified connection to command. Secondly you have to open connection.
Update: Complete Code
try
{
string connectionString = #"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\Database.mdf;Integrated Security=True;User Instance=True";
bool exists = false;
using (SqlConnection connection = new SqlConnection(connectionString))
{
connection .Open();
SqlCommand cmd = new SqlCommand("select * from [Users] where UserName = #UserName", connection );
cmd.Parameters.AddWithValue("UserName", tbUserName.Text);
exists = (int)cmd.ExecuteScalar() > 0;
}
if (exists)
{
lblUserName.Text = "This username has been used by another user.";
}
else
{
using(SqlConnection connection = new SqlConnection(connectionString))
{
connection.Open();
SqlCommand cmd = new SqlCommand("INSERT INTO Users (UserID,FName, LName, PhoneNo, Address, Email, UserName, Password, Points, Role) VALUES (#UserID,#FName, #LName, #PhoneNo, #Address, #Email, #UserName, #Password, #Points, #Role)", Connection);
cmd.Parameters.AddWithValue("#UserID", UserID);
cmd.Parameters.AddWithValue("#FName", tbFName.Text);
cmd.Parameters.AddWithValue("#LName", tbLName.Text);
cmd.Parameters.AddWithValue("#PhoneNo", tbPhoneNo.Text);
cmd.Parameters.AddWithValue("#Address", tbAddress.Text);
cmd.Parameters.AddWithValue("#Email", tbEmail.Text);
cmd.Parameters.AddWithValue("#UserName", tbUserName.Text);
cmd.Parameters.AddWithValue("#Password", tbPassword.Text);
cmd.Parameters.AddWithValue("#Points", Points);
cmd.Parameters.AddWithValue("#Role", Role);
cmd.ExecuteNonQuery();
}
}
}
catch(Exception ex)
{
//Do something
}
finally
{
//session
Session["UserName"] = tbUserName.Text;
Session["UserID"] = ("SELECT * FROM Users WHERE UserID = 'UserID'");
Session["Points"] = ("SELECT * FROM Users WHERE Points = 'Points'");
//pop out then redirect
ClientScript.RegisterStartupScript(this.GetType(), "Success", "<script type='text/javascript'>alert('Thank you or signing up with us!');window.location='Home.aspx';</script>'");
}
SQL command should have a overload which takes an initiated connection
Use SqlCommand constructor that takes connection as second argument. Next you have to open it before executing command and after that close it.
using (SqlCommand cmd = new SqlCommand("select * from [Users] where UserName = #UserName", connection))
{
cmd.Parameters.AddWithValue("UserName", tbUserName.Text);
connection.Open();
exists = (int)cmd.ExecuteScalar() > 0;
connection.Close();
}

SqlCommand AddWithValue

SqlCommand command = new SqlCommand("SELECT * FROM users WHERE Username = ? AND Password = ?", connection);
command.Parameters.AddWithValue("Username", username);
command.Parameters.AddWithValue("Password", password);
SqlDataReader reader = null;
reader = command.ExecuteReader();
When I run the program I get
Incorrect syntax near '?'.
On this line:
reader = command.ExecuteReader();
Can anyone see what I´m doing wrong?
using(SqlCommand command = new SqlCommand("SELECT * FROM users WHERE Username = #Username AND Password = #Password", connection))
{
command.Parameters.AddWithValue("#Username", username);
command.Parameters.AddWithValue("#Password", password);
using(SqlDataReader reader = command.ExecuteReader())
{
while(reader.Read())
{
//do actual works
}
}
}
Improved with using keywords, which is not necessary, but recommended
SqlCommand command = new SqlCommand(
"SELECT * FROM users WHERE Username = #Username AND Password = #Password",
connection);
command.Parameters.AddWithValue("Username", username);
command.Parameters.AddWithValue("Password", password);
SqlDataReader reader = null;
reader = command.ExecuteReader();
You might want to read up on sql.
Which DBMS are you using? If you're using SQL Server, that is incorrect syntax for the query. You need:
SqlCommand cmd =
new SqlCommand(#"select *
from users
where username = #username and password = #password");
command.Parameters.AddWithValue("#username", username);
command.Parameters.AddWithValue("#password", password);

Syntax error near Source when trying to access a database C# asp.net

string databaseLocation = "|DataDirectory|\\Users.mdf";
string connectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=" + databaseLocation + ";Integrated Security=True;User Instance=True";
SqlConnection sqlConnection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand();
command.CommandText = String.Format("SELECT * FROM Users WHERE Username = {0}", username);
command.CommandType = CommandType.Text;
command.Connection = sqlConnection;
sqlConnection.Open();
int numberOfRows = command.ExecuteNonQuery();
sqlConnection.Close();
return numberOfRows;
This should check the Users.mdf database for the number of occorances of the username. but im getting a "syntax error near Source" runtime error when it hits the ExecuteNonQuery. I cant find anything wrong... Please help :)
Your formatted sql statement is not including delimiters for the username:
command.CommandText = String.Format("SELECT * FROM Users WHERE Username = {0}", username);
sets the command text to something like:
SELECT * FROM Users WHERE Username = foo
This is easily corrected, but it would be better to use a SqlParameter:
command.CommandText = "SELECT * FROM Users WHERE Username = #username");
command.Parameters.AddWithValue("#username", username);
Also, ExecuteNonQuery will return -1 for the number of rows affected, since the select doesn't affect rows. Instead do:
command.CommandText = "SELECT COUNT(*) FROM Users WHERE Username = #username");
command.Parameters.AddWithValue("#username", username);
...
int numberOfRows = (int)command.ExecuteScalar();
Your code should be:
string databaseLocation = "|DataDirectory|\\Users.mdf";
string connectionString = "Data Source=.\\SQLEXPRESS;AttachDbFilename=" + databaseLocation + ";Integrated Security=True;User Instance=True";
SqlConnection sqlConnection = new SqlConnection(connectionString);
SqlCommand command = new SqlCommand();
command.CommandText = "SELECT COUNT(*) FROM Users WHERE Username = #User";
command.CommandType = CommandType.Text;
command.Parameters.AddWithValue("#User",username);
command.Connection = sqlConnection;
sqlConnection.Open();
int numberOfRows = command.ExecuteScalar();
sqlConnection.Close();
return numberOfRows;

Categories

Resources