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.
Related
This question already has answers here:
ASP.NET Identity 2.0 check if current user is in role IsInRole
(4 answers)
Unable to configure AspNet.Identity using PostgreSQL
(2 answers)
Closed 4 years ago.
I have a little web application on asp.net MVC + PostgreSQL.
I have login page, where people enters their login/password. Right now I only have 1 user - admin. If login and pass are correct, I enter to mainForm.aspx page.
But I need to make a couple of users: user and director. When user logs in, he needs to be redirected to user.aspx page, when director logs in, he needs to be redirected to director.aspx page. All cases need to make login/pass check from PostgreSQL database.
How do I do that?
Here's my Login.aspx.cs code with only 1 user:
namespace User1.WebApp
{
public partial class Login : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
this.UnobtrusiveValidationMode = System.Web.UI.UnobtrusiveValidationMode.None;
}
protected void Button_Login_Click(object sender, EventArgs e)
{
var connString = "Host=localhost;Username=postgres;Password=123;Database=postgres";
using (var conn = new NpgsqlConnection(connString))
{
conn.Open();
string checkuser = "select count(*) from Login where name= '" + TextBoxUserName.Text + "' ";
NpgsqlCommand com = new NpgsqlCommand(checkuser, conn);
int temp = Convert.ToInt32(com.ExecuteScalar().ToString());
if (temp == 1)
{
string checkPasswordQuery = "select password from Login where name= '" + TextBoxUserName.Text + "'";
NpgsqlCommand passCom = new NpgsqlCommand(checkPasswordQuery, conn);
string password = passCom.ExecuteScalar().ToString().Replace(" ", "");
if (password == TextBoxPassword.Text)
{
Session["New"] = TextBoxUserName.Text;
Response.Redirect("MainForm.aspx");
}
else
{
Response.Write("Password is NOT correct !");
}
}
else
{
Response.Write("Username is NOT correct !");
}
}
}
}
}
You could do this just before
Response.Redirect("MainForm.aspx");
The way you can do it is to check the type of user and act accordingly.
Few comments regarding the current code:
Set the connection string in web.config and read it from there instead of having it hard coded in your code e.g. here.
The way you create your SQL statements makes your application vulnerable to SQL injection, one of the most common ways for someone to hack a site. Instead of doing this, prefer parameterized queries.
You make two round trips to the database, to check if the user exists and then to get her password. What about if you want to fetch one more information like the user type ? You would make one more round trip. You could eliminate all this to one round trip, provided that you can identify your users based on something unique like the username. Just fetch all the data for a specific username.
Let that someone can get access to the Login table of your database. How exposed are your application users ? 100%. All the passwords there are in clear text ! You should avoid this in any way. A naive solution is to hash the password and each time someone try to login to hash the password that the user provides and compare with the hash you have stored. A more professional approach of storing passwords is described at The right way to implement password hashing using PBKDF2 and C#. Look also for similar articles like the mentioned one. Security should be of paramount importance for your applications.
Are you able to store an extra field in the database to specify whether a login is Admin, User or Director?
You could use an Enum for this:
enum LoginRole
{
User = 0,
Director = 1,
Admin = 2
}
This Enum could be stored as an integer field in your Login table, called "role" or similar. You could then redirect to the appropriate page depending on this role.
I have updated your code with an example:
var connString = "Host=localhost;Username=postgres;Password=123;Database=postgres";
using (var conn = new NpgsqlConnection(connString))
{
conn.Open();
string checkuser = "select password, role from Login where name=#username";
using (var com = new NpgsqlCommand(checkuser, conn))
{
com.Parameters.AddWithValue("#username", TextBoxUserName.Text);
using (var reader = com.ExecuteReader())
{
if (reader.Read())
{
string password = reader["password"].ToString();
LoginRole role = (LoginRole)reader["role"];
if (password == TextBoxPassword.Text)
{
Session["New"] = TextBoxUserName.Text;
switch (role)
{
case LoginRole.User:
Response.Redirect("user.aspx");
break;
case LoginRole.Admin:
Response.Redirect("MainForm.aspx");
break;
case LoginRole.Director:
Response.Redirect("director.aspx");
break;
}
}
else
Response.Write("Password is NOT correct !");
}
else
Response.Write("Username is NOT correct !");
}
}
}
Please note, using parameters in your queries in this case would be preferred, as appending the string from the textbox straight into the SQL query is vulnerable to SQL injection.
You were also making two calls to the database per login - one to check the username and another to check the password. I have addressed this in my above sample to only make one call to the database.
I wrote some code for search page as follows
I declared variables in above page load as follows
static String strsql = "";
in page load
if(!isPostback)
{
if(session["username"] != null)
{
loadprofiles(); // calling loadprofiles method
bindlist();//loading gridview data
}
}
now loadprofiles method wrote as follows
protected void loadprofiles()
{
strsql = "select * from admintable where userid = '"+session["username"].Tostring()+"'";
}
now bindlist method is as follows
private void bindlist()
{
SqlCommand comm1 = new SqlCommand(strsql, connection);
//and some code for binding data to gridview
}
the problem is while two different users are login into this page from two different computers the user getting the data from second login persions
please help me to solve this problem...
thanks in advance
I was having Session issue for multiple tabs in a single browser.
In Default.aspx/Index.aspx write below code to generate a Unique session Id's.
if (Page.IsPostBack == false) //If page loads for the first time
{
ViewState["_PageID"] = Guid.NewGuid();
}
To store any variable in session Use the following lines:
Session[ViewState["_PageID"].ToString() + "username"] = "testuserName";
To access anything stored based on the Session Id:
string userNameInSession = Session[ViewState["_PageID"].ToString() + "username"] as string;
You cannot declare strsql as static since it will store value for all users - user1 will have access to the user2 strsql value. You have to remember that static is a member of a type, not an instance - it will be accessible for all users until AppDomain is unloaded.
In my opinion you shouldn't store SQL query in a variable(it seems unnecessary since session is accessible everywhere in your code).
I'd change your code to the
private void bindlist()
{
SqlCommand comm1 = new SqlCommand("select * from admintable where userid = '"+session["username"].Tostring()+"'", connection);
//and some code for binding data to gridview
}
EDIT:
Since you want to reuse query, you can return it from loadprofiles() method like follows:
protected string loadprofiles()
{
strsql = "select * from admintable where userid = '"+session["username"].Tostring()+"'";
// Do your logic there...
return strsql;
}
and use it:
if(!isPostback)
{
if(session["username"] != null)
{
var strsql = loadprofiles(); // calling loadprofiles method
bindlist(strsql);//loading gridview data
}
}
I believe you get the point.
I am trying to develop a simple user management system for the admin of the web application. I am using ASP.NET Wizard Control for this task.
I just put a TextBox for writing the username and when the admin clicks on the Next button, the system should check if the username existed in the database or not. If it is existed, the system should display his information in a placeholder for the admin.
I am struggling with this task. I did the following in the code-behind:
//For checking the user
if (Request.QueryString["Username"] != null)
{
String strUserName = Request.QueryString["Username"];
//Check userName Here
String strReturnStatus = "false";
if (CheckUsername(Request.QueryString["Username"]) == true)
{
strReturnStatus = "true";
}
Response.Clear();
Response.Write(strReturnStatus);
Response.End();
}
Now, I think to create a second method called CheckUsername which I don't know what I should put it inside it:
private bool CheckUsername(string p)
{
//throw new NotImplementedException();
}
It may seem that this question is simple or stupid, but I am a new developer and I could not be able to find a simple resource that could help me in this issue particularly.
I believe the following method is what you're after:
private bool CheckUsername(string username)
{
string connString = "";
string cmdText = "SELECT COUNT(*) FROM Users WHERE Username = #username";
using(SqlConnection conn = new SqlConnection(connString))
{
conn.Open(); // Open DB connection.
using(SqlCommand cmd = new SqlCommand(cmdText, conn))
{
cmd.Parameters.AddWithValue("#username", username)); // Add the SQL parameter.
int count = (int)cmd.ExecuteScalar();
// True (> 0) when the username exists, false (= 0) when the username does not exist.
return (count > 0);
}
}
}
You can fill in the blanks (e.g specify a connection string connString and modify cmdText). The SQL query I specified in cmdText is under the assumption of a typical user management system where you have common table names and columns; Users (table) and Username (column). It's hard to justify as you haven't specified the structure. Modify it to suit your applications needs.
The method of counting how many records exist is quite common in most cases. I frequently use that method of checking/validating things as I see fit.
Further information about the code (classes) I used in my example above:
http://msdn.microsoft.com/en-us/library/system.data.sqlclient.aspx
I also advise you read about data access (not that link). I'll leave you to that.
I adjust some point in your code:
if (!string.IsNullOrEmpty(Request.QueryString["Username"]))
{
---
---
if (CheckUsername(Request.QueryString["Username"]))
{
---
---
}
Refer to this link as tutorial for your task: http://www.codeproject.com/KB/database/sql_in_csharp.aspx
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");
}
}
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.