IndexOutOfRange exception in SqlDataReader in asp.net c# - c#

I am fed up with this error. At the time of login I am authenticating user and then loading some important information in session variables. I hosted my application on IIS and client computers use the application through IP address. Here is my c# code...
protected void btnLogin_Click(object sender, EventArgs e)
{
Session["UserName"] = txtUserName.Text;
string DefaultYear = GetDefaultFinYear();
if (DefaultYear != string.Empty)
{
DefaultYear = "connect" + DefaultYear;
Connections.Init(DefaultYear);
SqlDataAdapter adp = new SqlDataAdapter();
SqlDataReader dr = null;
try
{
adp = new SqlDataAdapter("CheckLogin_sp", Connections.Connection[Session["UserName"].ToString()]);
adp.SelectCommand.Parameters.AddWithValue("#UserName", txtUserName.Text.Trim());
adp.SelectCommand.Parameters.AddWithValue("#Pwd", txtPassword.Text.Trim());
adp.SelectCommand.Parameters.AddWithValue("option", "Authenticate".Trim());
adp.SelectCommand.CommandType = CommandType.StoredProcedure;
if (Connections.Connection[Session["UserName"].ToString()].State == ConnectionState.Closed)
{
Connections.Connection[Session["UserName"].ToString()].Open();
}
dr = adp.SelectCommand.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
Session["Name"] = dr[0].ToString();
Session["CompanyName"] = dr[1].ToString();
Session["UserId"] = dr[2].ToString();
Session["Center"] = dr[3].ToString();
Session["ClientCode"] = dr[4].ToString();
Session["UserImage"] = dr[5].ToString();
Session["CurrentDatabase"] = dr[6].ToString();
Connections.BillReport = dr[7].ToString();
Connections.DuesReport = dr[8].ToString();
Connections.GeneralReport = dr[9].ToString();
Connections.PendingReport = dr[10].ToString();
Connections.RadiologyReport = dr[11].ToString();
Connections.HistoReport = dr[12].ToString();
}
Session["value"] = "admin";
Response.Redirect("~/Masters/home.aspx", false);
}
else
{
MessageBox.Show("Invalid Password");
txtUserName.Text = string.Empty;
}
}
catch (Exception ex)
{
Response.Write(ex.ToString());
}
finally
{
Connections.Connection[Session["UserName"].ToString()].Close();
adp.Dispose();
dr.Close();
dr.Dispose();
}
}
else
{
MessageBox.Show("Invalid UserName");
}
}
Not every time this error occurs but sometimes when multiple computers access the application this error comes on following line
Session["Name"] = dr[0].ToString();
Note:- Once this error occurs it resolve only when the server computer restart.

I believe wrapping your code in the stored procedure with a transaction would fix your problem.
BEGIN TRY
BEGIN TRANSACTION CheckLogin
--Existing SQL code
COMMIT TRANSACTION CheckLogin
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION CheckLogin
END CATCH
All stored procedures called from a web application should use transactions.

Related

How to check if user in mysql database exists (in c#)

So I know this is a often asked question but I want to check if the username is already taken in the database using c#. I tried this:
MySqlCommand cmd2 = new MySqlCommand("SELECT * FROM tablename WHERE(name = '" + tb1.Text + "');");
cmd2.Connection = connect;
connect.Open();
string unt = "";
try
{
MySqlDataReader dr;
dr = cmd.ExecuteReader();
while (dr.Read())
{
unt= dr.GetString("name");
}
dr.Close();
}
catch (Exception ex)
{
errorbox.Content = ex.Message;
}
finally
{
connect.Close();
}
if(unt == "" || unt == "0") {
continuel = false;
tb2.Text = "User " +tb1.Text+ " doesn't exist!";
Popup1.IsOpen = true;
}
Its a WPF project and the variable 'continuel' is set to true by default. The code doesn't recognize if a user doesn't exist.
First off your code is vulnerable to sql inject, you should never concatenate values into a query. secondly you can do a count and execute a scalar. Not I stripped down your code a little you'll have to add error handling back.
bool userExists = false;
private String sql = "SELECT COUNT(*) FROM tableName WHERE name = #usernameparam;";
MySqlCommand m = new MySqlCommand(sql);
m.Parameters.AddWithValue("#usernameparam", tb1.Text.Trim());
int userCount = Convert.ToInt32(m.ExecuteScalar());
if(userCount>0)
{
userExists = true;
}
//use userExists variable to evaluate if user exists

Update query not throwing error

Thanks for the help in advance.
Im trying to use update query in C#
Error : command is getting executed even if I use incorrect values
Design view
Code :
protected void Button1_Click(object sender, EventArgs e)
{
try
{
con.Open();
cmd = new SqlCommand("update Comcast_AvayaID set Status='Inactive' where Employee_Id='" + TxtEMPID.Text + "' and AvayaID ='" + TxtAvayaID.Text + "'", con);
cmd = new SqlCommand("UPDATE Avaya_Id SET Status = 'UnAssigned' where Avaya_ID ='" + TxtAvayaID.Text + "'", con);
cmd.ExecuteNonQuery();
LBLSuccess.Visible = true;
LBLSuccess.Text = "Deactivation Successfull";
con.Close();
}
catch (SqlException ex)
{
LBLSuccess.Visible = true;
LBLSuccess.Text = "Deactivation Unsuccessfull";
}
your code would look better like this, it not the most optimal, but ia already a way better piece of code then your snippet
1) added parameters using a helper function for the sql injection issue
2) an ExecuteNonQuery returns the rows affected, so if you are expecting that 1 row was updated, you can check on that
3) if you update a row with an id that not exists, it will not throw a SqlException like you are expecting in your code, this happens e.g. when locking occurs
public void Update()
{
var con = new SqlConnection();
try
{
var empId = TxtEMPID.Text
var avayaId = TxtAvayaID.Text
con.Open();
var cmd1 = new SqlCommand("update Comcast_AvayaID set Status='Inactive' where Employee_Id=#empId and AvayaID = #avayaId", con);
cmd1.Parameters.Add(AddParameter("#empId",empId));
cmd1.Parameters.Add(AddParameter("#avayaId", avayaId));
var cmd2 = new SqlCommand("UPDATE Avaya_Id SET Status = 'UnAssigned' where Avaya_ID =avayaId", con);
cmd2.Parameters.Add(AddParameter("#avayaId", avayaId));
var rowsaffected1 = cmd1.ExecuteNonQuery();
var rowsAffected2 = cmd2.ExecuteNonQuery();
if (rowsaffected1 == 1 && rowsAffected2 == 1)
{
//success code goes here
//--------
LBLSuccess.Visible = true;
LBLSuccess.Text = "Deactivation Successfull";
}
else
{
// failure code goes here
//-----------------------
LBLSuccess.Visible = true;
LBLSuccess.Text = "Deactivation Unsuccessfull";
}
}
catch (SqlException ex)
{
//handle errors
}
finally
{
con.Close();
}
Console.ReadLine();
}
private SqlParameter AddParameter(string name, object value) {
var par = new SqlParameter();
par.ParameterName = name;
par.Value = value;
return par;
}
If you put "incorrect" values it just updates zero of records. No errors/exception expected here.

ASP.NET C# Validating username and password

Im trying to validate username and password from an MySql server. Login validation is working, but I can't for the life of me figure out why the "Create new user" validation isn't working.
Here are the code for registering new user. What happens is;
catch (Exception)
{
Label1.Text = "Brukernavnet er allerede i bruk";
}
Seems like this part ^ is ruining it for me somehow, whenever i test run this code I get this message.
protected void newBtn_Click(object sender, EventArgs e)
{
String cs = "Database=trafikkskole; User=user; Password=password";
MySqlConnection dbconnect = new MySqlConnection(cs);
try
{
dbconnect.Open();
cmd.CommandText = "INSERT INTO user (username, password) VALUES (#un, #pw)";
cmd.Parameters.AddWithValue("#un", inputUser.Text);
cmd.Parameters.AddWithValue("#pw", inputPw.Text);
cmd.Connection = dbconnect;
int a = cmd.ExecuteNonQuery();
if (a > 0)
{
Label1.Text = "Gratulerer! Du har nå laget en bruker!";
}
else
{
Label1.Text = "ERROR";
}
}
catch (Exception)
{
Label1.Text = "Brukernavnet er allerede i bruk";
}
finally
{
dbconnect.Close();
}
}
}
EDIT:
If I try it like this:
protected void newBtn_Click(object sender, EventArgs e)
{
String cs = "Database=trafikkskole; User=root; Password=root";
MySqlConnection dbconnect = new MySqlConnection(cs);
String sql = "SELECT * FROM user";
MySqlCommand cmd = new MySqlCommand(sql, dbconnect);
da = new MySqlDataAdapter(cmd);
MySqlCommandBuilder cb = new MySqlCommandBuilder(da);
ds = new DataSet("TEST");
da.Fill(ds, "user");
Response.Write(ds.Tables["user"].Rows.Count);
try
{
dbconnect.Open();
cmd.CommandText = "INSERT INTO user (username, password) VALUES (#un, #pw)";
cmd.Parameters.AddWithValue("#un", inputUser.Text);
cmd.Parameters.AddWithValue("#pw", inputPw.Text);
cmd.Connection = dbconnect;
int a = cmd.ExecuteNonQuery();
if (a > 0)
{
Label1.Text = "Gratulerer! Du har nå laget en bruker!";
}
else
{
Label1.Text = "ERROR";
}
}
catch (Exception Exception)
{
Label1.Text = "Brukernavnet er allerede i bruk";
}
finally
{
dbconnect.Close();
}
}
}
This ends up with the possibility of making a user without username or password.
There are a number of things that could be going wrong. You should examine the exception.message to get insights as to what it could be.
For example, put a break point in the catch statement and see if the exception thrown for things like... does the username already exist and SQL is throwing an error. ... or are the username/password null, too long, etc...
Regardless, change the catch statement to catch(Exception exception) and see what the exception is.
I want to thank everyone for trying, found a working solution, will post it here for future reference.
protected void newBtn_Click(object sender, EventArgs e)
{
String cs = "Database=trafikkskole; User=root; Password=root";
MySqlConnection dbconnect = new MySqlConnection(cs);
try
{
if (!string.IsNullOrWhiteSpace(inputUser.Text) && !string.IsNullOrWhiteSpace(inputPw.Text))
{
dbconnect.Open();
Label1.Text = "Gratulerer! Du har nå laget en bruker!";
string qry = "INSERT INTO user(username, password) VALUES (#un, #pw)";
cmd = new MySqlCommand(qry, dbconnect);
cmd.Parameters.AddWithValue("#un", inputUser.Text);
cmd.Parameters.AddWithValue("#pw", inputPw.Text);
cmd.Connection = dbconnect;
cmd.ExecuteNonQuery();
}
else
{
Label1.Text = "ERROR";
}
}
catch (Exception)
{
Label1.Text = "Brukernavnet er allerede i bruk";
}
finally
{
dbconnect.Close();
}
}

How to determine the user role that received from database if admin or not

i want to to take the user name and password to the database and get the user role according to the inserted user name and password but this code does not work
public bool Login(out string Msg)
{
bool b = true;
Msg = "";
SqlConnection con = new SqlConnection(connection.connectstr);
try
{
con.Open();
SqlCommand com = new SqlCommand("user_proc", con);
com.CommandType = CommandType.StoredProcedure;
com.Parameters.Add("#u_name", SqlDbType.NVarChar).Value = this.u_name;
com.Parameters.Add("#u_password", SqlDbType.NVarChar).Value = this.u_password;
com.ExecuteNonQuery();
con.Close();
b = true;
}
catch (Exception ex)
{
con.Close();
Msg = ex.Message;
b = false;
}
return b;
}
and the c# code that should check the role into database and redirect me to server page if admin and client page if not:-
protected void btn_login_Click(object sender, EventArgs e)
{
my_user u = new my_user();
u.u_name = TextBox1.Text;
u.u_password = TextBox2.Text;
string m="";
if (!u.Login(out m))
{
lbl_role.Text = "error";
}
else
{
if (u.u_role == "admin")
{
Response.Redirect("testclient.aspx");
}
else Response.Redirect("testserver.aspx");
}
}
and the database procedure that performs that task is:
create procedure user_proc
(#u_name nvarchar(50) ,
#u_password nvarchar(50),
#u_role nvarchar(50))
as
begin
begin try
begin transaction
if exists (select u_role from user_sys
where u_name=#u_name and u_password= #u_password)
commit
End try
Begin catch
rollback
declare #msg varchar(200)
set #msg = ERROR_MESSAGE()
raiserror(#msg , 16 , 1)
End catch
End
hehe , look, there's no need to do this complicated
In the DB you have a user table with name,pass and role
so, the role is admin or not
then, i suggest
In your app check with SqlExecuteScalar
public bool IsAdmin(string u_name, string u_password)
{
string role="";
string sql = "select u_role from user_sys
where u_name=#u_name and u_password= #u_password";
using (SqlConnection conn = new SqlConnection(connection.connectstr))
{
SqlCommand cmd = new SqlCommand(sql, conn);
cmd.Parameters.Add(new SqlParameter("#u_name", u_name));
cmd.Parameters.Add(new SqlParameter("#u_password", u_password));
try
{
conn.Open();
role = cmd.ExecuteScalar().ToString();
}
catch (Exception ex)
{
//handle error
}
}
return role == "admin";
}
Finally call it
string u_name = TextBox1.Text;
string u_password = TextBox2.Text;
if (IsAdmin(u_username,u_password))
//it is admin
else
//it is not admin
Bye bye and have fun !

ASP.Net C# - try-catch-finally and using statements [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
So I've been used to coding with try-catch-finally statements and not including the using statement and I'm trying to incorporate the latter into my code.
I've attached my original and revised code below. Is this revision sufficient?
Also, regarding catching for errors, I've seen the following code used a number of times on here. When should this be used/not used since this doesn't inform users about the error?
catch (Exception ex)
{
throw ex;
}
original code:
protected void signIn()
{
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
MySqlConnection conn = new MySqlConnection(connStr);
MySqlCommand comm;
comm = new MySqlCommand("Select user_id, username, email, salt, hashed_pw, role, activated FROM users WHERE username=#username", conn);
comm.Parameters.Add("#username", MySqlDbType.VarChar);
comm.Parameters["#username"].Value = txtUsername.Text;
MySqlDataReader reader;
try
{
conn.Open();
reader = comm.ExecuteReader();
if (reader.Read())
{
string saltAndPwd = String.Concat(txtPassword.Text, reader["salt"].ToString());
string hashSaltAndPwd = FormsAuthentication.HashPasswordForStoringInConfigFile(saltAndPwd, "sha1");
if (hashSaltAndPwd.Equals(reader["hashed_pw"].ToString()))
{
if (reader["activated"].ToString().Equals("Y"))
{
Session["Username"] = reader["username"].ToString();
Session["Role"] = reader["role"].ToString();
Session["UserID"] = reader["user_id"].ToString();
Session["EmailAddress"] = reader["email"].ToString();
if (reader["role"].ToString().Equals("0"))
{
Session["PermanentRole"] = "admin";
}
else if (reader["role"].ToString().Equals("2"))
{
Session["PermanentRole"] = "tutor";
}
Response.Redirect("~/portal.aspx");
}
else
{
lblError.Text = "Your account has not been activated. Please check your inbox and activate your account or reset your password by clicking the link above.";
}
}
else
{
lblError.Text = "Incorrect password.";
}
}
else
{
lblError.Text = "Username does not exist.";
}
reader.Close();
}
catch
{
lblError.Text = "Database connection error. Please try again.";
}
finally
{
conn.Close();
}
}
revised code:
protected void signIn()
{
string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
using (MySqlConnection conn = new MySqlConnection(connStr))
{
using (MySqlCommand cmd = conn.CreateCommand())
{
string cmdText = "Select user_id, username, email, salt, hashed_pw, role, activated FROM users WHERE username=#username";
cmd.CommandText = cmdText;
cmd.Parameters.Add("#username", MySqlDbType.VarChar);
cmd.Parameters["#username"].Value = txtUsername.Text;
try
{
conn.Open();
reader = cmd.ExecuteReader();
if (reader.Read())
{
string saltAndPwd = String.Concat(txtPassword.Text, reader["salt"].ToString());
string hashSaltAndPwd = FormsAuthentication.HashPasswordForStoringInConfigFile(saltAndPwd, "sha1");
if (hashSaltAndPwd.Equals(reader["hashed_pw"].ToString()))
{
if (reader["activated"].ToString().Equals("Y"))
{
Session["Username"] = reader["username"].ToString();
Session["Role"] = reader["role"].ToString();
Session["UserID"] = reader["user_id"].ToString();
Session["EmailAddress"] = reader["email"].ToString();
if (reader["role"].ToString().Equals("0"))
{
Session["PermanentRole"] = "admin";
}
else if (reader["role"].ToString().Equals("2"))
{
Session["PermanentRole"] = "tutor";
}
Response.Redirect("~/portal.aspx");
}
else
{
lblError.Text = "Your account has not been activated. Please check your inbox and activate your account or reset your password by clicking the link above.";
}
}
else
{
lblError.Text = "Incorrect password.";
}
}
else
{
lblError.Text = "Username does not exist.";
}
reader.Close();
}
catch
{
lblError.Text = "Database connection error. Please try again.";
}
finally
{
conn.Close();
}
}
}
1) conn.Close(); is not necessary since the using statement will call close for you. It is equivalent to
MySqlConnection conn = new MySqlConnection(connStr)
try
{
....
}
finally
{
conn.Close();
}
2) The catch with the form
catch (Exception ex)
{
throw ex;
}
is not recommended in any situation I can think of. It has 2 problems
It's doing nothing except rethrowing the exception. You don't catch the exception unless you want to do something with it (e.g.: logging the error)
Rethrowing the exception doing throw ex; cuts the stack trace. Anyone catching that exception will see the error as generated on that line, losing useful information
You don't need the finally { ...} because the using will Dispose the connection.
Your question about:
catch (Exception ex)
{
throw ex;
}
Is common when you want to Log the exception but still throw it, simply catching and re-throwing serves no purpose.
But should be done like this:
catch (Exception ex)
{
LogManager.Log(ex);
throw; //rethrow
}

Categories

Resources