just trying to learn asp.net
i am able to login and redirect to default.aspx.
i am trying to check if user's usere name and password are right from database(able to do).
now i am trying to store user name in session(not able to do, here i am getting nullpointer/value error) and show this session value as welcome message on next page/redirected page.my code is as:
protected void Button1_Click(object sender, EventArgs e)
{
SqlDataReader dr;
SqlConnection con = new SqlConnection("Data Source=xxxx-pc\\ddd;Initial Catalog=db_Login;User Id=sd;Password=ds;");
con.Open();
SqlCommand com = new SqlCommand("select password from tab_userinformation where Username='" + txt_uname.Text + "'", con);
dr = com.ExecuteReader();
if (dr.HasRows)
{
dr.Read();
if (dr[0].ToString() == txt_pwd.Text)
{
Response.Redirect("default_Page.aspx");
//Response.Redirect("erp.htm");
Session["user"] = txt_uname.Text;
here i am getting object reference not set to an instance of an object exception for Session["user"]
any suggestion
Thanks!
Because before assigning value to session, you are redirecting to another page.
Response.Redirect("default_Page.aspx");
//Response.Redirect("erp.htm");
Session["user"] = txt_uname.Text; // this is not executing...
You have to assign value before redirecting to page. e.g.
Session["user"] = txt_uname.Text; // this is not executing...
Response.Redirect("default_Page.aspx");
//Response.Redirect("erp.htm");
Store the value in your Session before the Redirect:
Session["user"] = txt_uname.Text;
Response.Redirect("default_Page.aspx");
That way you don't lose the value of txtuname.Text.
Also, you should use parameterized queries for your SQL - the way you currently have it, you are open to SQL Injection Attacks.
Check:
In aspx there is a text control which has id = "txt_uname"
Make sure this text control has runtat = server.
The above code should be like this:
if (dr[0].ToString() == txt_pwd.Text)
{
Session["user"] = txt_uname.Text;
Response.Redirect("default_Page.aspx");
this would work. Once you redirect to some other page, control doesn't return to the statements after the "redirec". Hence they aren't executed. Instead statements inside page load of "default_Page" would start executing
The statements after Response.Redirect() wont be executed because this (Redirect) method transfer a user to another page.
Suggestion: Don't use hard-coded sql string. Use parameterized sql statements or stored-procedures.
string password=string.Empty;
using(SqlConnection con = new SqlConnection("Data Source=xxxx-pc\\ddd;Initial Catalog=db_Login;User Id=sd;Password=ds;"))
{
using(SqlCommand com = new SqlCommand("select password from tab_userinformation where Username=#p1", con))
{
com.Parameters.AddWithValue("#p1",txt_uname.Text);
con.Open();
object retValue=com.ExecuteScalar();
if(retValue!=null)
{
password=retValue.ToString();
}
con.Close();
}
}
if (!string.IsNullOrEmpty(password))
{
if (password== txt_pwd.Text)
{
Session["user"] = txt_uname.Text;
Response.Redirect("default_Page.aspx");
}
}
Related
I am a noob attempting to create a login page where the user enters their username and password that is already in the sqldatabase connected to the textboxes/button/form. The below code is my best attempt at doing so, but upon debugging it throws catch despite the textbox values entered being registered in the sql database. If any additional information is needed please ask.
private bool compareStoD(string teststring1, string teststring2)
{
return String.Compare(teststring1, teststring2, true, System.Globalization.CultureInfo.InvariantCulture) == 0 ? true : false;
}
private void button1_Click_1(object sender, EventArgs e)
{
try
{
SqlConnection connection = new SqlConnection(#"Data Source=DESKTOP-P3JSE1C;Initial Catalog=logins;Integrated Security=True");
connection.Open();
SqlCommand checker = new SqlCommand("SELECT COUNT (*) from users WHERE username='" + textBox1.Text + "'AND pssword='" + textBox3.Text + "'", connection);
SqlDataReader reader = checker.ExecuteReader();
string usernameText = textBox1.Text;
string psswordText = textBox3.Text;
while (reader.Read())
{
if (this.compareStoD(reader["username"].ToString(), textBox1.Text) && // replace textbox1.Text with text string usernameText
this.compareStoD(reader["pssword"].ToString(), textBox3.Text)) //replace textbox3.Text with text string psswordText
{
main wen = new main();
wen.Show();
}
}
reader.Close();
connection.Close();
}
catch
{
MessageBox.Show("Incorrect password or username.");
}
}
It is most likely throwing an exception because your query is asking for the count but then you are reading columns username and password which do not exist in the reader. This is your query:
SELECT COUNT (*)
Change that to this:
SELECT username, password ...
Also, unless you want every savvy user to access your application, use SqlParameter to avoid SQL Injection
Another Suggestion
I am not sure what main is, my assumption it is some window, but I would not show it where you are showing right now. Try to close the reader as soon as possible and then show the window if the user is authenticated like this.
bool userIsAuthenticated = false;
if (reader.Read())
{
// if a row was returned, it must be the row for the user you queried
userIsAuthenticated = true;
}
reader.Close();
connection.Close();
// Now that the reader is closed, you can show the window so the reader does not stay
// open during the duration of the main window
if (userIsAuthenticated)
{
main wen = new main();
wen.Show();
}
Select count returns the count not the row, if you want the row itself change to select username, password instead of select count(*) . See this link
There is over work being done by your code. You are querying the database by comparing the username and password values from UI to the values in the table. And once and if values are retrieved from the database you are again comparing value from UI to the values coming from the database. This is unnecessary.
The query will return the values only if values match in the database so you don't need to compare them again. So method compareStoD is not required at all.
The button1_Click can be changed as following to make it simpler.
private void button1_Click_1(object sender, EventArgs e)
{
try
{
SqlConnection connection = new SqlConnection(#"Data Source=DESKTOP-P3JSE1C;Initial Catalog=logins;Integrated Security=True");
connection.Open();
SqlCommand checker = new SqlCommand("SELECT COUNT (*) from users WHERE username=#userName AND pssword = #password", connection);
checker.Parameters.Add(new SqlParameter("#userName", textBox1.Text));
checker.Parameters.Add(new SqlParameter("#password", textBox3.Text));
var count = Convert.ToInt32(checker.ExecuteScalar());
connection.Close();
if(count > 0)
{
main wen = new main();
wen.Show();
}
else
{
MessageBox.Show("Incorrect password or username.");
}
}
catch
{
MessageBox.Show("Incorrect password or username.");
}
}
Also one good practice while supplying values from Textbox, you should use Textbox.Text.Trim() which helps in eliminating the spaces at the beginning and end. These spaces can create a problem in later stage.
I'm trying to upgrade the db from users' input, but it doesn't work...
I'm using this:
protected void Button1_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection(strcon);
SqlCommand cmd = new SqlCommand();
SqlCommand ncmd = new SqlCommand("Update Utenti Set Nome = #vnome where [Indirizzo E-Mail]=#vem", con);
ncmd.Parameters.AddWithValue("#vem", Session["[Indirizzo E-Mail]"].ToString());
ncmd.Parameters.AddWithValue("#vnome", TextBox2.Text);
ncmd.Connection = con;
con.Open();
ncmd.ExecuteNonQuery();
con.Close();
Label2.Text = "Dati aggiornati con successo!";
Response.Redirect("~/ModificaDati.aspx");
}
When I click on the button it show me the Label2 text, but in the database the "Nome" is not changed, why?
Thanks before for the answers ^^
I would change your method as below
if (Session["[Indirizzo E-Mail]"] != null &&
!string.IsNullOrEmpty(Session["[Indirizzo E-Mail]"].ToString()) &&
!string.IsNullOrEmpty(TextBox2.Text))
{
string vem = Session["[Indirizzo E-Mail]"].ToString();
using (var con = new SqlConnection(strcon))
using (var ncmd = new SqlCommand("Update Utenti Set Nome = #vnome where [Indirizzo E-Mail]=#vem", con))
{
con.Open();
ncmd.Parameters.AddWithValue("#vem", vem);
ncmd.Parameters.AddWithValue("#vnome", TextBox2.Text);
int rows = ncmd.ExecuteNonQuery();
Label2.Text = rows + " Dati aggiornati con successo!";
}
}
Response.Redirect("~/ModificaDati.aspx");
Added input validation, session values can be null, better to check before you update database
when you create SqlCommand you can give the connection, no need to set it again
make sure your SQL is valid
use using statements for disposable objects like SqlConnection, SqlCommand
Your code looks ok. Just make sure you check if SQL is correct as Damith already suggested.
Another thing I’s recommend is additionally validating your parameters for data type correctness before executing the query.
Using this approach you’ll probably avoid a lot of unnecessary exceptions and also be able to provide more user friendly messages. Of course this only applies if user input is non text type
//Data Type verification
DateTime tmp;
if (!DateTime.TryParse(Label2.Text.Trim(), out tmp))
{
//Show error message that this is not a correct data type
}
Open your connection first
con.Open();
ncmd.Connection = con;
Hope it helps
the code i'm using is below. Is this the proper way to use Session? also how do I call companyID and userID to clarify, if i did Session. is it Session.Contents or Session.Keys? this is my first time using session, I know I use httpcontact.current.user to access most of this but i'm not sure how to access each part of the data.
Thanks!
MySqlConnection cn = new MySqlConnection("Server=localhost;Database=users; User=root;Password=00;");
cn.Open();
string storedProcedureName = "VLID";
MySqlCommand cmd = new MySqlCommand(storedProcedureName, cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("#userName", this.Login1.UserName);
cmd.Parameters.Add("#passwordID", this.Login1.Password);
MySqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
dr.Read();
string userID = dr["userID"].ToString();
string companyID = dr["CompanyID"].ToString();
string sessionID = Session.SessionID.ToString();
Session.Add(companyID, "companyID");
Session.Add(userID, "userID");
e.Authenticated = true;
Response.Redirect("index.html");
// Event Authenticate is true
}
You are calling Session.Add method a little backwards:
Session.Add takes a key and a value, in that order; therefore, on your code you want:
Session.Add("companyID",companyID );
Session.Add("userID",userID );
But instead, you could do this, too:
Session["companyID"]=companyID;
Session["userID"]=userID;
Then, whenever you need to retrieve the userID value that you stored previously, you can do:
string userID= Session["userID"] as string;
As a side note, I wouldn't mix data access code on the UI code as you are doing.
The code that gets the data from the database should be moved to the data access layer (DAL).
And when you instantiate a database connection, always enclose it in an using statement so that is properly disposed when it comes out of scope:
using(MySqlConnection cn = new MySqlConnection("Server=localhost;Database=users; User=root;Password=00;"))
{
cn.Open();
//rest of the code
}
I am creating a login form. Where if the Login-id and password matches with the values stored in Register table it retrieves all values from Register table and the result stores in the SqlDataReader object .So, now I want to access accountid and type from this table.How can we do it?
To understand what I am trying to say please have a look on the following code-
--------------------Login.aspx.cs---------------------------------------------------------------
protected void Submit_Click(object sender, EventArgs e)
{
string conStr = ConfigurationManager.ConnectionStrings["ROCConStr"].ConnectionString;
SqlConnection scon = new SqlConnection(conStr);
scon.Open();
SqlCommand cmd = new SqlCommand("select* from Register where email= #login_id and pwd=#password", scon);
SqlParameter Para;
Para = cmd.Parameters.Add("#login_id", SqlDbType.Char);
Para.Value = email.Text;
Para = cmd.Parameters.Add("#password", SqlDbType.Char);
Para.Value = pwd.Text;
SqlDataReader reader = cmd.ExecuteReader();
if(reader.HasRows)
{if (reader["account_type"]=="admin") /* error - Please see the bottom for more details.*/
Response.Redirect("http://localhost:1187/roc/WelcomeAdmin.aspx");
else
Response.Redirect("http://localhost:1187/roc/WelcomeUser.aspx");}
else
{ Label1.Text = "UserID or password is incorrect."; }
reader.Close();
scon.Close();
}
==================================================
<br>About the erro:- reader["account_type"]=="admin"
I dont know how to retrieve the value of a single column.So, I just typed to show what I want to do. I tested this code I got the error - "Invalid attempt to read when no data is present."
You need to call reader.Read() to move to the first row.
Alternatively, change your query to select only the column you want, then call ExecuteScalar to return that value directly (or null if there were no rows) without using a DataReader at all.
(you can't do this, since you want more than one column)
You've only checked to see if you 'HasRows'; but you still need to advance the Reader. reader.Read()
That should fix your problem. You might want to also consider incorporating 'using' statements to limit the scope of your objects and modifying your URLs to use relative paths instead of absolute. That way, if you deploy to a new environment or move servers you don't have to remove the hard-coded URL.
Can any one teach me how to use sessions? I have a login page which refers to mysql db table named User which includes UserID="variable number", username and password. Id like to be able to store the userid in a session so I can call it inside the users profile when he logs in.
How is this done? Any relevant coding and placement of specific coding would be helpful as Im just not picking it up at all. Does it go inside the code behind (.cs file) or is it held in the html of the aspx page? or both and how? How does the session work across multiple inner pages (once logged in you can broswe more than one page related to your own profile)
using System.Data.Odbc;
partial class login : System.Web.UI.Page
{
protected void Login1_Authenticate(object sender, System.Web.UI.WebControls.AuthenticateEventArgs e)
{
OdbcConnection cn = new OdbcConnection("Driver={MySQL ODBC 3.51 Driver};Server=localhost;Database=mydb; User=root;Password=;");
cn.Open();
OdbcCommand cmd = new OdbcCommand("Select * from login where username=? and password=?", cn);
//Add parameters to get the username and password
cmd.Parameters.Add("#username", OdbcType.VarChar);
cmd.Parameters["#username"].Value = this.Login1.UserName;
cmd.Parameters.Add("#password", OdbcType.VarChar);
cmd.Parameters["#password"].Value = this.Login1.Password;
OdbcDataReader dr = default(OdbcDataReader);
// Initialise a reader to read the rows from the login table.
// If row exists, the login is successful
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
e.Authenticated = true;
// Event Authenticate is true
}
}
}
In C#, to store a variable in a Session variable:
Session["usrID"]="myUserName";
Later, to retrieve the Session variable:
string usrName = Convert.ToString(Session["usrID"]);
http://msdn.microsoft.com/en-us/library/ms178581.aspx
Basically, give yourself a property for each variable in the page class, eg.
private int SelectedYear
{
get
{
object obj = Session["SelectedYear"];
if (obj != null)
{
return int.Parse(obj.ToString());
}
else
{
return 0;
}
}
set { Session["SelectedYear"] = value; }
}
if you need something for user management, you should go with a membershipprovider. http://msdn.microsoft.com/en-us/library/f1kyba5e.aspx
to get userinformation you can use
Membership.GetUser()
if you just want to use sessions to store variables, you can easily use
Session["name"] = value;
var value = Session["name"];
like others already mentionend
When should you call the code to set the Session variable value?
You can do that in the Login_Authenticate method. That it where you have first retrieved the ID.
Or, you can do it in the Global.asax file, in the Session_Start event. Then, you will always have the value available on every page.