Comparing against database value - c#

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.

Related

c# SqlDataReader Not Finding Value

My Problem has Been Fixed, My main problem was getting the information from the textbox in the xaml which got erased after that window was closed and another opened. Though the answers did fix my other problems and have made my code much simpler and easier to read. So thank you very much!
So I am Currently working on building a Calendar for a personal project and working on adding events to a Database, this table for Events stores two varchars, and an int (name, description, userid), the userid is a foreign key and is linked to the User Table. When I use the code below to try and pull the userid for the username that the person entered, it tells me that there is no existing value.
using (SqlConnection connection = new SqlConnection())
{
connection.ConnectionString =
"Data Source=calenderserver.database.windows.net;" +
"Initial Catalog=Calender;" +
"User id=*******;" +
"Password=*******;" +
"MultipleActiveResultSets = true";
connection.Open();
SqlCommand com = new SqlCommand("Select UserId from Users Where UserName = #user", connection);
com.Parameters.AddWithValue("#user", UsernameTextBox.Text);
SqlDataReader reader = com.ExecuteReader();
reader.Read();
int userid = reader.GetInt32(1);
messages.Text = "Event Added";
SqlCommand command = new SqlCommand("INSERT INTO [Events] VALUES (#eventname, #eventdesc)", connection);
command.Parameters.AddWithValue("#eventname", name);
command.Parameters.AddWithValue("#eventdesc", description);
command.Parameters.AddWithValue("#userid", userid);
command.ExecuteNonQuery();
reader.Close();
connection.Close();
}
Even though when I run the same command in an actual SQL Query it returns a proper value.
SQL Command
I am completely lost on this and have checked multiple sources and solutions and would really appreciate the help.
You are doing int userid = reader.GetInt32(1); the indexes for the get function are 0 based so you actually need int userid = reader.GetInt32(0); so you get the first column.
That being said, because you are using the first result of the first column you can simplify your code by switching from a data reader to using ExecuteScalar()
SqlCommand com = new SqlCommand("Select UserId from Users Where UserName = #user", connection);
com.Parameters.AddWithValue("#user", UsernameTextBox.Text);
int userid = (int)com.ExecuteScalar();
Try using ExecuteScalar function. Execute scalar returns a single value and I see you only need the user ID.
Take a look at this link .
int userid = (Int32)com.ExecuteScalar();
I Hope it helps!
Indices in GetInt32 are 0-based as per doc, therefore your call should read:
int userid = reader.GetInt32(0);
Change these lines:
SqlDataReader reader = com.ExecuteReader();
reader.Read();
int userid = reader.GetInt32(1);
to:
var userID = com.ExecuteScalar();
Why:
Execute Scalar should be used when your query returns a single value.
Execute Reader returns a collection of data in the form of a DataReader. DataReaders are fast, and you can quickly iterate over them to get the data you need from the database. The connection remains open as long as the datareader is open.
Because you were only getting a single value back from the database, it makes sense to use ExecuteScalar. It's more efficient and too the point.
If you were getting a list of UserID's, then I'd recommend you use a DataReader to iterate through the UserIDs.

SQL query sentence

I'm working on a C# project with some data bases. I'm getting an error when executing the following function:
//Returns true if the username and password are correct. Otherwise it returns false.
public bool LogInto(string name, string pass, OleDbConnection cnx)
{
DataTable res = new DataTable();
OleDbDataAdapter adp = new OleDbDataAdapter("SELECT User,Password FROM UserPassword WHERE (User='"+name+"' AND Password='"+pass+"')", cnx);
adp.Fill(res);
bool found = false;
String user = Convert.ToString(res.Rows[0]["User"]);
String password = Convert.ToString(res.Rows[0]["Password"]);
if (name==user && pass==password)
found = true;
return found;
}
So this is the full function, however I'm getting an error, I just replaced && with AND. But it still doesn't work. I'm getting ("There was an error parsing the query. // Token number, token line offset, token in error.
What's wrong with it? I had the same function but instead of taking just one row from the data table, it took the whole table and with a loop it looked the row we were looking for. However, I'm trying to do this one, just taking the row we need, because it is more efficient.
Could you guys help me? I can't find my mistake.
Thank you so much
You have some issues with the query:
The and operator in SQL is and, not &&
The query is WIDE OPEN FOR SQL INJECTION ATTACKS. You have to escape the strings to be correctly interpreted as string literals.
You can do it like this:
string query =
"SELECT User, Password FROM UserPassword WHERE Username = '" +
name.Replace("\\", "\\\\").Replace("'", "\\'") +
"' and Password = '" +
pass.Replace("\\", "\\\\").Replace("'", "\\'") +
"'";
Note: This way to escape the strings is specific to MySQL. Each database have a different set of characters that needs to be escaped, and in different ways.
If possible you should use a parameterised query instead of concatenating string into the query. That makes it easier to get it correct.
First please use parameterized one like this, with IDisposable inherited
using(SqlCommand cmd = new SqlCommand())
{
cmd.CommandType = CommandType.Text;
cmd.CommandText = #""SELECT up.User, up.Password FROM dbo.UserPassword up WHERE up.Username = #Param1" AND Password = #Param2;
cmd.Parameters.Add("#Param1", SqlDbType.Varchar).Value = 'ABC';
.............
}
second try to encrypt it or hash it, there are lot of information about hashing and encrytion on web

Determining if user login already exists in database?

I am building a web application in asp.net using C#. I have the Form where the user should register and then can login. I am having a problem in making the web app know that the name which the user picks is either "already exists" or not. If it already exists it should not insert the same name and display a message saying "user name already exists". I have tried the SqlDataReader but no luck.
protected void Register_Button_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["BJ_Player_String"].ToString());
SqlCommand cmd = new SqlCommand();
SqlCommand cmd2 = new SqlCommand();
SqlDataReader data_reader;
String name = TextBox2.Text;
String date = TextBox3.Text;
try
{
conn.Open();
cmd = new SqlCommand("Insert into BJ_Player (Player_Name, D_O_B) Values (#Player_name, #D_O_B)", conn);
cmd = new SqlCommand("Select Player_Name from BJ_Player WHERE Player_Name = #Player_name", conn);
cmd.Parameters.Add("#Player_name", SqlDbType.NVarChar).Value = name;
cmd.Parameters.Add("#D_O_B", SqlDbType.Date).Value = date;
cmd.Connection = conn;
data_reader = cmd.ExecuteReader();
cmd.ExecuteNonQuery();
if (data_reader.HasRows)
{
lblPlayerNameExists.Visible = true;
}
else
{
// do nothing
}
}
Make Player_Name unique in database then it will give you exception when you try to insert. You have to use unique constraint.
You have to give command type also and check you assigned both queries to same cmd object
in your code you're inserting data in your DB and then you are examining that the name is the same or not.
first you should search the name in your DB and then if there isn't any record with that name ,you should add your record.
I usually do it in one of two ways:
Create stored procedure that will check for name uniqueness and insert new record if everything is ok. It should return status as numeric code that you will check.
Check for name uniqueness before saving it using as a part of validation process.
Using the merge statement may help with this. Merge performs insert, update, or delete operations on a target table based on the results of a join with a source table.
Basically it inserts when needed, and updates when needed. Often times referred to as an upsert. but it gets the job done.
Here is a link to a site explaining how to use merge. Looks like a good article.
http://www.kodyaz.com/articles/sql-server-2008-t-sql-merge-statement-example.aspx
If you would like to write a model function to do that then
Leave it for ajax check which is pretty similar to the second
method
Issue "Select username from DB-table" to retrieve
usernames then check the username input against them before
displaying a view to report a problem if any or showing a message to
tell the user that "this name is valid", for example.

Iterating through a column in a database

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.

How to save a SQL "Select" result in a variable in C#

I'm using Visual C# connected to MySQL for study purposes and I'm stuck in throwing an error to the user when he types a username that already exists.
Current code to put things into the database (it may be useless, once my question may be much more about SQL):
s = new sql(); // This calls a class that works as an adapter to connect form with the database
Conn = s.Connection;
Conn.Open();
coma = Conn.CreateCommand();
coma.CommandText = "INSERT INTO test.test (`user`,`password`) VALUES ('"+username.Text+"','"+password.Text+"');";
coma.ExecuteNonQuery();
What I want to do it compare "username.Text" ("username" is a TextBox) with the values on database's "test" table and, if some value match, evoke a MessageBox.Show("Hey guy, this username is already in use! Try something different)
Some points about your code sample
You want to be sure that you dispose of your connection and command objects. For my answer, I've wrapped them in using statements which will take care of that for me.
You do not want to go to the database with unsanitized inputs. I am going to use parameterized queries in the example.
It's not a good idea to store passwords in plain text. I am not going to demonstrate more secure techniques, just know to look for information about encrypting passwords, salt keys, etc.
And now for some code. In this, I'm using OleDb objects, retrofit to your particular database. And, of course, provide appropriate names to tables, columns, etc.
using (OleDbConnection connection = SomeMethodReturningConnection())
using (OleDbCommand command = SomeMethodReturningCommand())
{
command.Parameters.Add(new OleDbParameter("#username", username));
command.CommandText = "Select Count(*) From Users where Username = #username";
connection.Open();
int output = (int)command.ExecuteScalar();
if (output > 0)
{
// username already exists, provide appropriate action
}
else
{
// perform insert
// note: #username parameter already exists, do not need to add again
command.Parameters.Add(new OleDbParameter("#password", password));
command.CommandText = "Insert Into Users (Username, Password) Values (#username, #password)";
command.ExecuteNonQuery();
}
}
Thank you Anthony! Your answer put me on the right track. Although there is something that the people who will read this post should change from your code in order to get it working with Odbc connectors: the way as parameters are parsed and the way as the textbox content is extracted:
using (OdbcConnection connection = SomeMethodReturningConnection())
using (OdbcCommand command = SomeMethodReturningCommand())
{
command.Parameters.Add(new OdbcParameter("#username", username.Text));
command.CommandText = "Select Count(*) From Users where Username = ?";
connection.Open();
int output = (int)command.ExecuteScalar();
if (output > 0)
{
// username already exists, provide appropriate action
}
else
{
// perform insert
// note: #username parameter already exists, do not need to add again
command.Parameters.Add(new OdbcParameter("#password", password.Text));
command.CommandText = "Insert Into Users (Username, Password) Values (?,?)**";
command.ExecuteNonQuery();
}
}
Thank you anyway!

Categories