Object reference not set to an instance of an object. ExecuteScalar() - c#

I am always getting "Object reference not set to an instance of an object". I dont know what i did wrong. I did try to execute the query: "select count(*) from Registration where Username='Myname' and it returned 1;
The code:
protected void Button1_Click(object sender, EventArgs e)
{
DBConnect con = new DBConnect();
string query = "select count(*) from Registration where Username='" + TextBox1.Text + "'";
//Open connection
if (con.OpenConnection() == true)
{
//Create Command
MySqlCommand cmd = new MySqlCommand(query, con.Initialize());
//Create a data reader and Execute the command
int temp = Convert.ToInt32(cmd.ExecuteScalar().ToString());
if (temp == 1)
{
string query1 = "Select Password from Registration where Username='" + TextBox1.Text + "'";
MySqlCommand pass = new MySqlCommand(query1, con.Initialize());
string password = pass.ExecuteScalar().ToString();
if (password == TextBox2.Text)
{
Session["new"] = TextBox1.Text;
Response.Redirect("GreenhouseHomepage.aspx");
}
else
{
Label1.Text = "Invalid Password...!!";
Label1.Visible = true;
}
}
else
{
Label1.Text = "Invalid Username...!!";
Label1.Visible = true;
}
}
//close Connection
con.CloseConnection();
}
The Error:

Give this a try.
//Open connection
if (con.OpenConnection() == true)
{
// Since you know that the connection is open, you can just
// pass the entire conn object
MySqlCommand cmd = new MySqlCommand(query, con);
//Create a data reader and Execute the command
int temp = Convert.ToInt32(cmd.ExecuteScalar());
The COUNT(*) will return 0 if no records are found so you will always get a value from your syntax.

Related

.Rows.Count always returns -1 even if record in database already exists?

Basically I want to check, using c#, if there is a username in the database already existing. If there is not-it must be created.
Below is the code that is doing exactly that(only the checking part matters in my opinion, but I have added the code for the adding part anyways)
Problem is that no matter what-if it exists or not, it always returns -1
public Boolean checkUser()
{
var connection = new MySqlConnection("Server=127.0.0.1;Database=book_library;user=root;password=root2");
var table = new DataTable();
connection.Open();
string checkUsernameQuery = "SELECT * FROM accounts WHERE username = 'usernameInputField.Text'";
var adapter = new MySqlDataAdapter();
MySqlCommand command = new MySqlCommand(checkUsernameQuery, connection);
//command.Parameters.Add("#username", MySqlDbType.VarChar).Value = usernameInputField.Text;
adapter.SelectCommand = command;
adapter.Fill(table);
if (table.Rows.Count > 0)
{
return true;
}
else
{
return false;
}
}
Here is the adding part(just adding it, but it is not too related with the problem)
private void registerIconButton_Click(object sender, EventArgs e)
{
checkUser();
var connection = new MySqlConnection("Server=127.0.0.1;Database=book_library;user=root;password=root2");
connection.Open();
string insertQuery = "INSERT INTO `accounts` (username, password, email) VALUES ('" + usernameInputField.Text + "','" + passwordInputField.Text + "','" + emailInputField.Text + "')";
MySqlCommand command = new MySqlCommand(insertQuery, connection);
command.Parameters.Add("#username", MySqlDbType.VarChar).Value = usernameInputField.Text;
command.Parameters.Add("#password", MySqlDbType.VarChar).Value = passwordInputField.Text;
command.Parameters.Add("#email", MySqlDbType.VarChar).Value = emailInputField.Text;
if (checkUser())
{
MessageBox.Show("This username already exists!");
}
else
{
if (command.ExecuteNonQuery() == 1)
{
}
else
{
MessageBox.Show("ERROR");
}
}
connection.Close();
}
Connections and Commands are disposable so you should put them inside using blocks to deterministically clean up resources.
If you just want to know if something exists, you can use ExecuteScalar instead of using a heavy-weight adapter.
Then just return the result of the expression != null to get your boolean that indicates if the user is there or not.
using(var connection = new MySqlConnection("Server=127.0.0.1;Database=book_library;user=root;password=root2"))
using(var cmd = connection.CreateCommand())
{
connection.Open();
string checkUsernameQuery = "SELECT TOP 1 username FROM accounts WHERE username = #p1";
cmd.Parameters.Add(new MySqlParameter("#p1", MySqlDbType.VarChar).Value = usernameInputField.Text;
var user = cmd.ExecuteScalar();
return user != null;
}

Check if username is in the database using ASP.Net

I want to check if a username is already in the database. It comes along with my update statement. I have this code and I do not know where to put the select statement:
protected void btn_update_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(conn);
con.Open();
str = "update UserData set Password=#Password where UserName='" + txtUser.Text + "'";
com = new SqlCommand(str, con);
com.Parameters.Add(new SqlParameter("#Password", SqlDbType.VarChar));
com.Parameters["#Password"].Value = BusinessLayer.ShoppingCart.CreateSHAHash(txtPW.Text);
com.ExecuteNonQuery();
con.Close();
Label1.Visible = true;
Label1.Text = "Password changed Successfully!" ;
con.Close();
}
I want something like
"Select Username from Userdata Where Username = txtUser.Text"
You don't need a SELECT here. ExecuteNonQuery() returns the number of rows affected, which means that when it returns 0, there was no user with the given name in the database. If all went well, it should return 1.
Your code is vulnerable to SQL injection and leaks resources. Here's a better version:
protected void btn_update_Click(object sender, EventArgs e)
{
using(var con = new SqlConnection(conn))
{
con.Open();
var commandTest = "update UserData set Password=#Password where UserName=#Username";
using(var com = new SqlCommand(commandTest, con))
{
com.Parameters.AddWithValue("#Username", txtUser.Text);
com.Parameters.AddWithValue("#Password", BusinessLayer.ShoppingCart.CreateSHAHash(txtPW.Text));
if(com.ExecuteNonQuery() == 1)
{
Label1.Visible = true;
Label1.Text = "Password changed Successfully!" ;
}
}
}
}

Error: The type 'System.Data.OleDb.OleDbDataReader' has no constructors defined

I am trying to change password option with ms access database....
please help me folks....
here the code:
default.aspx.cs
protected void Button1_Click(object sender, EventArgs e)
{
try
{
OleDbConnection myCon = new OleDbConnection(ConfigurationManager.ConnectionStrings["vhgroupconnection"].ConnectionString);
myCon.Open();
string userid = txtuserid.Text;
string oldpass = txtoldpass.Text;
string newPass = txtnewpass.Text;
string conPass = txtconfirmpass.Text;
string q = "select user_id,passwd from register where user_id = #userid and passwd = #oldpass";
OleDbCommand cmd = new OleDbCommand(q, myCon);
OleDbDataReader reader = new OleDbDataReader();
cmd.Parameters.AddWithValue("#userid", txtuserid.Text);
cmd.Parameters.AddWithValue("#oldpass", txtoldpass.Text);
reader = cmd.ExecuteReader();
reader.Read();
if (reader["user_id"].ToString() != String.Empty && reader["passwd"].ToString() != String.Empty)
{
if (newPass.Trim() != conPass.Trim())
{
lblmsg.Text = "New Password and old password does not match";
}
else
{
q = "UPDATE register SET passwd = #newPass WHERE user_id =#userid";
cmd = new OleDbCommand(q, myCon);
cmd.Parameters.AddWithValue("#newPasss", txtnewpass.Text);
cmd.Parameters.AddWithValue("#userod", txtuserid.Text);
cmd.Parameters.AddWithValue("#passwd", txtoldpass.Text);
int count = cmd.ExecuteNonQuery();
if (count > 0)
{
lblmsg.Text = "Password changed successfully";
}
else
{
lblmsg.Text = "password not changed";
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}
also check pls.....
Compilation Error Description: An error occurred during the
compilation of a resource required to service this request. Please
review the following specific error details and modify your source
code appropriately.
Compiler Error Message: CS0143: The type
'System.Data.OleDb.OleDbDataReader' has no constructors defined
Source Error:
Line 36: OleDbCommand cmd = new OleDbCommand(q, myCon);
Line 37:
Line 38: OleDbDataReader reader = new OleDbDataReader();
Line 39:
Line 40:
As error message says; OleDbDataReader has no constructor.
From documentation of OleDbDataReader;
To create an OleDbDataReader, you must call the ExecuteReader method
of the OleDbCommand object, instead of directly using a constructor.
You can use ExecuteReader method that returns OleDbDataReader
OleDbDataReader dr = cmd.ExecuteReader();
And you need add your parameter values before you call ExecuteReader method.
Also use using statement to dispose your OleDbConnection, OleDbCommand and OleDbDataReader like;
using(OleDbConnection myCon = new OleDbConnection(conString))
using(OleDbCommand cmd = myCon.CreateCommand())
{
//Define your sql query and add your parameter values.
using(OleDbDataReader dr = cmd.ExecuteReader())
{
//
}
}
And as Steve mentioned, OleDbDataReader.Read method returns boolean value (true of false) and it reads your OleDbDataReader results row by row. You might need to consider to use the result of this method like in a while statement. For example;
while(reader.Read())
{
//Reads your results until the last row..
}
As a final words, I strongly suspect you store your passwords as plain text. Don't do that! Use SHA-512 hash.
As MSDN clearly states, To create an OleDbDataReader, you must call the ExecuteReader method of the OleDbCommand object, instead of directly using a constructor.
You cannot instantiate it using new, which is what you are doing and which is why you get the error. Remove the offending line and change it to this to get rid of the error:
OleDbDataReader reader = cmd.ExecuteReader();
Also, remember to use using blocks to ensure resources get properly disposed.
using(OleDbConnection myCon = new OleDbConnection(ConfigurationManager.ConnectionStrings["vhgroupconnection"].ConnectionString))
{
OleDbCommand cmd = new OleDbCommand(q, myCon);
//Add parameters etc
OleDbDataReader reader = cmd.ExecuteReader();
//Rest of the processing
}
Problem: You try to make new instance of OleDbDataReader by calling new OleDbDataReader() instead you should create a reader using OleDbCommand.ExecuteReader().
In the following code notice use of using statement (this should ensure connection closing or reader closing for the case of OleDbDataReader).
protected void Button1_Click(object sender, EventArgs e)
{
try
{
string sConnString = ConfigurationManager.ConnectionStrings["vhgroupconnection"].ConnectionString;
using(OleDbConnection myCon = new OleDbConnection(sConnString))
{
myCon.Open();
string userid = txtuserid.Text;
string oldpass = txtoldpass.Text;
string newPass = txtnewpass.Text;
string conPass = txtconfirmpass.Text;
string q = "select user_id,passwd from register where user_id = #userid and passwd = #oldpass";
OleDbCommand cmd = new OleDbCommand(q, myCon);
cmd.Parameters.AddWithValue("#userid", txtuserid.Text);
cmd.Parameters.AddWithValue("#oldpass", txtoldpass.Text);
string sUserId = string.Empty;
string sPass = string.Empty;
using(OleDbDataReader reader = cmd.ExecuteReader())
{
if(reader.Read()) //assumption: one record returned
{
sUserId = reader["user_id"].ToString();
sPass = reader["passwd"].ToString();
}
}
if (sUserId != string.Empty && sPass != string.Empty)
{
if (newPass.Trim() != conPass.Trim())
lblmsg.Text = "New Password and old password does not match";
else
{
q = "UPDATE register SET passwd = #newPass WHERE user_id =#userid";
cmd = new OleDbCommand(q, myCon);
cmd.Parameters.AddWithValue("#newPass", txtnewpass.Text);
cmd.Parameters.AddWithValue("#userid", txtuserid.Text);
int count = cmd.ExecuteNonQuery();
if (count > 0)
lblmsg.Text = "Password changed successfully";
else
lblmsg.Text = "password not changed";
}
}
}
}
catch (Exception ex)
{
throw ex;
}
}

I want to check the username is already exists in my database table or not?

i have registration page and i want to check that username is already exist in database or not in 3 tier architecture.
MyRegistration.cs:
public static int checkusername(string user_txt)
{
int id2 = 0;
string selectstr = "select * from xyz where UserName = '" + user_txt + " ' ";
id2 = DataAccessLayer.ExecuteReader(selectstr);
return id2;
}
and the code behind onclick event of textbox:
protected void txt_username_TextChanged(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txt_username.Text))
{
int id = xyz.checkusername(txt_username.Text.Trim());
if (id > 0)
{
lblStatus.Text = "UserName Already Taken";
}
else
{
lblStatus.Text = "UserName Available";
}
}
}
DataAccessLayer:
public static int ExecuteReader(string Query)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = GetConnectionString();
con.Open();
int id = 0;
SqlCommand cmd = new SqlCommand();
cmd.CommandText = Query;
cmd.CommandType = System.Data.CommandType.Text;
cmd.Connection = con;
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
{
id++;
}
cmd = null;
reader.Close();
con.Close();
return id;
}
I have edited some of your codes try like below... it will help you...
Text change Event :
protected void txt_username_TextChanged(object sender, EventArgs e)
{
if (!string.IsNullOrEmpty(txt_username.Text))
{
if (xyz.checkusername(txt_username.Text.Trim()))
{
lblStatus.Text = "UserName Already Taken";
}
else
{
lblStatus.Text = "UserName Available";
}
}
}
Check Username :
public bool CheckUsername(string user_txt)
{
bool Result;
Result = DataAccessLayer.ExecuteReader(user_txt);
return Result;
}
Excute Reader :
public bool ExecuteReader(string user_txt)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = GetConnectionString();
con.Open();
SqlCommand cmd = new SqlCommand("select * from xyz where UserName = #UserID", con);
SqlParameter param = new SqlParameter();
param.ParameterName = "#UserID";
param.Value = user_txt;
cmd.Parameters.Add(param);
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
return true;
else
return false;
}
Usually if the "select query" doesn't find a userName with the parameter user_txt you'll id2 will be end up with the value -1. So the appropriate code would be:
if (id ==-1)
{
lblStatus.Text = "UserName Available";
}
if (id>0)
{
lblStatus.Text = "UserName Already Taken";
}
By the way, your code is highly insecure and your database can be easily attacked using SQL Injection I'd recommend you to understand this issue and add parameters to the query to prevent it. C# has its ways to implement this. Don't try to fix the access to the database, just start from scrath keeping in mind SQL Injection.
As others have mentioned, this approach has potentially serious security issues.
However, your problem may lie here user_txt + " ' ". The spaces around the second ', specifically the one before it may lead to the usernames not matching as expected.

Unable to Make this log in Form in c# / SqlDataReader Issue

I am trying to make a windows Form Application with a login screen,Form3 Will open Form1 if the username and password are correct.
The code is linked to a database
The code is as follows:
private void button1_Click(object sender, EventArgs e)
{
string u_id = textBox1.Text;
string u_pwd = textBox2.Text;
SqlConnection conn = new SqlConnection("Data Source=mmtsql.XXX.XXXXX.ac.uk;Initial Catalog=mmt12-186;User ID=XXXXXX;Password=XXXXXX");
conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = ("SELECT * FROM UsersData WHERE User = '" + textBox1.Text + "'");
cmd.Parameters.AddWithValue("un", u_id);
SqlDataReader reader = cmd.ExecuteReader();
if (reader.Read() == false)
{
label3.Text = "Invalid Username or Password !";
return;
}
string realpwd = reader.GetString(0);
if (u_pwd == realpwd)
{
Form1 formload = new Form1();
formload.Show();
}
}
Every time I run this code, I get an exception on with the line:
string realpwd = reader.GetString(0);
The exception is:
Invalid attempt to read when no data is present.
The UsersData table has 3 columns, Id, User, Password
Thanks goes to "Alfred Sanz" who answered the question, the problem now is that no error is present but no data is shown, as if the button1_click has no method, the current code is:
private void button1_Click(object sender, EventArgs e)
{
string u_id = textBox1.Text;
string u_pwd = textBox2.Text;
SqlConnection conn = new SqlConnection("Data Source=mmtsql.XX.XXX.ac.uk;Initial Catalog=XXXXXXX ;User ID=XXXX;Password=XXXXX");
conn.Open();
SqlCommand cmd = conn.CreateCommand();
cmd.CommandText = ("SELECT * FROM UsersData WHERE User = #un");
cmd.Parameters.AddWithValue("#un", u_id);
SqlDataReader reader = cmd.ExecuteReader();
while (reader.Read())
if (reader["Password"].ToString() == u_pwd)
{
Form1 formload = new Form1();
formload.Show();
}
else
{
label3.Text = "Invalid Username or Password !";
}
}
you already set the value of USER as '" + textBox1.Text + "'" but you are also setting a value cmd.Parameters.AddWithValue("un", u_id); which really does not exist, change your code into
cmd.CommandText = "SELECT * FROM UsersData WHERE User = #un";
cmd.Parameters.AddWithValue("#un", u_id);
and also you can change the reader part to:
while (reader.Read())
{
if (reader["Password"].ToString() == u_pwd.Text
{
Form1 formload = new Form1();
formload.Show();
}
else
{
label3.Text = "Invalid Username or Password !";
}
}

Categories

Resources