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.
Related
I'm trying to update a Database table and getting the error
"MySql.Data.MySqlClient.MySqlException: 'You have an error in your SQL
syntax; check the manual that corresponds to your MySQL server version
for the right syntax to use near 'group='superadmin' WHERE
identifier='steam:steam:1100001098b5888'' at line 1'"
// Creates query to run
public void UpdateInfo(String jobTitle, int jobGrade, String adminLevel, String identifier) {
// Opens the database connection if it's not already open
if (!(databaseConnected)) {
openConnection();
}
// Creates query to run
String query = "UPDATE " + table + " SET job=#jobTitle, job_grade=#jobGrade, group=#adminLevel WHERE identifier=#identifier";
// Makes a new command
MySqlCommand cmd = new MySqlCommand(query, connection);
// Replaces the # placeholders with actual variables
cmd.Parameters.AddWithValue("#jobTitle", jobTitle);
cmd.Parameters.AddWithValue("#jobGrade", jobGrade);
cmd.Parameters.AddWithValue("#adminLevel", adminLevel);
cmd.Parameters.AddWithValue("#identifier", identifier);
// Executes it and if it's...
if (cmd.ExecuteNonQuery() > 0) {
// Successful
MessageBox.Show("Successfully updated information");
closeConnection();
return;
} else {
// Not successful
MessageBox.Show("Error with updating information!");
// Closes the connection again to prevent leaks
closeConnection();
return;
}
}
I tried your query on https://sqltest.net/ and noticed it highlighted "group" when I tried to create the table. I'm wondering if the problem might be the usage of "group" as a column name since it's a reserved word.
Is it possible to try renaming the column to group_level or adding back ticks around 'group' or "group" and seeing if that works?
So for example
'group'=#grouplevel
I found this thread and this thread on renaming the column where they had issues with "group" as a column name. Adding backticks seemed to solve both problems.
EDIT: As per OP, double quotes (") solved the issue instead of single. Edited answer to include.
Try change query like this
String query = "UPDATE " + table + " SET job='#jobTitle', job_grade=#jobGrade, group='#adminLevel' WHERE identifier='#identifier'";
if you input String value with query, you need to use 'this' for work
I hope this will work for you.
if not, you can use String.Format for that like this.
String Query = String.Format("Update `{0}` Set job='{1}', job_grade={2}, group='{3}' Where identifier='{4}'", table, jobTitle, jobGrade, adminLevel, identifier);
I am working with Microsoft SQL Server Management Studio, and C# .net
My code fetches string data from the webBrowser, stores it in a textbox, compares it with values in my database, and gets the corresponding int ID to that string. Now, this int ID is displayed in a textbox (optional), and is then stored in another table in my database.
My code is as follows:
string p = dComm.executeScalar("select StateID from StateMaster where StateCode='" + txtState.Text + "'");
textBox1.Text = p;
Convert.ToInt32(p);
This fetches the StateID, and displays it in a textbox. I then open another table from the database, and put the value as shown below.
dTbl = dComm.openDataTable("CompanyMaster", "select * from CompanyMaster where 1=0 ");
DataRow dRow;
dRow = dTbl.NewRow();
dRow["StateID"] = p;
Now, this code works perfectly fine when i run the code on the HTML file of the page, but if I try to run it directly from the web browser, it gives an error
Input String was not in a correct format
The error is shown at the line:
Convert.ToInt32(p);
Am I missing something? Can anyone help me with this?
The problem you are having:
Convert.To is relatively hard work, and shouldn't (in my eyes) be used when the input can come from the end user. When bad data is provided to the Convert.To it gives exceptions that cannot be handled very well.
For example:
textbox1.Text = "test";
Convert.ToInt32(textbox1.text);
It will crash and burn.
I would advise you get into the routine of using TryParse, which handles bad values much better.
Example:
int test = 0;
int.TryParse(textbox1.text, out test)
{
//do validation with if statements
}
This would cancel out any bad data, and also ensure that the end user would only get user friendly message boxes that you have wrote yourself. Meaning you can tell them where they have put in a bad value so that they can correct it without the program crashing and burning.
Try using Int32.Parse(p) instead. You can also use the TryParse if you don't want an exception on a failed parse, and instead you would get a bool that shows whether it was successful or not.
So from your example, it would be like this...
string p = dComm.executeScalar("select StateID from StateMaster where StateCode='" + txtState.Text + "'");
textBox1.Text = p;
int pInt = Int32.Parse(p);
Or if you want to use TryParse, it would be like this...
string p = dComm.executeScalar("select StateID from StateMaster where StateCode='" + txtState.Text + "'");
textBox1.Text = p;
int pInt;
if(!Int32.TryParse(p, out pInt))
{
//Parsing failed, do something about it
}
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.
I am making a Login Page. For that i am going to do authenticate the username and password from database. As i execute the program query will run and it return a -1 value. As the username and password is correct. Please Help me out. My program code is as Follow:
public partial class Home : System.Web.UI.Page
{
SqlConnection objcon;
String query;
SqlCommand cmd;
int num;
//SqlDataAdapter DataAdapter;
protected void Page_Load(object sender, EventArgs e)//db open in page load.
{
objcon = new SqlConnection("Data Source String");
objcon.Open();
}
//query execution and authentication on button click
protected void Button1_Click(object sender, EventArgs e)
{
query = "select * from tbl_user where UserName='" + txtUname.Text + "' and Password='" + txtPwd.Text + "'";
cmd = new SqlCommand(query,objcon);
num = cmd.ExecuteNonQuery();
//Label3.Text = num.ToString();
if (num == -1)
Label3.Text = "Correct";
else
Label3.Text = "Incorrect";
objcon.Close();
}
}
Look at this code:
num = cmd.ExecuteNonQuery();
Now given that you're creating a command based on a variable called query, do you really think calling a method with the phrase non-query in it makes sense? From the docs for ExecuteNonQuery, if you're not convinced yet:
For UPDATE, INSERT, and DELETE statements, the return value is the number of rows affected by the command. [...] For all other types of statements, the return value is -1.
Your statement is a SELECT query, so it's returning -1 exactly as documented.
I suspect you should be using ExecuteScalar or ExecuteReader. For example, if you're trying to get the number of matches, you should use:
SELECT COUNT(*) ... (rest of query, parameterized of course)
Personally I prefer that over taking -1 or null as per James's answer, but it's a matter of taste.
If you're not trying to get the count of matches, it's not clear why you're assigning to an int variable in the first place.
EDIT: Additional issues: (As already mentioned in comments)
Only create and open the SqlConnection when you need to, not in the constructor
Use using directives for both the SqlConnection and SqlCommand to they're closed even when there's an exception
Don't include user input directly in SQL - use parameterized SQL instead, to SQL avoid injection attacks, improve code/data separation, and avoid conversion errors
Don't store your users' password directly in the database in plaintext - that's a really horrible thing for any web site to do.
Don't try to write your own user authentication code in the first place - it's been done for you already, in many different places
What you want is to execute a scalar query, meaning that it returns a single value. In the case of your query, if the username and password match, simply select -1:
SELECT -1 FROM tblUser WHERE Username = 'James' AND Password = 'Johnson'
If a value is returned, that value will be -1 and you know you have a match. If no value (null) is returned it didn't match.
EDIT
Aside from just answering your question, there are some major problems with your code that you need to address:
You're opening a new connection each time the page loads. That's a big no-no! Not only are you opening a new connection on each page load, but you're also not closing the connection once the query has executed.
Instead of using concatenation to build your query, use a parameterized query to avoid the risk of SQL injection. Someone with even a little knowledge of SQL could easily escape your query and wreak havoc on your data.
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.