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
}
Related
I'm trying to implement the status of a current logged in user in an WPF application. I can read from the database and set that value once , but i need it to keep updating. So for example when a user is online, and he changes to busy. The value would be online, but once it changed on the database to busy , the value would update to busy too.
for example:
connection = new MySqlConnection(connectionString);
Query = "SELECT status FROM Accounts WHERE username=#username";
connection = new MySqlConnection(connectionString);
MySqlCommand command = new MySqlCommand(Query, connection);
command.CommandType = System.Data.CommandType.Text;
command.Parameters.AddWithValue("#username", thedesiredusername);
connection.Open();
MySqlDataReader dataReader = command.ExecuteReader();
while (dataReader.Read())
{
string userstatus = dataReader.GetString("status");
}
This would set the userstatus value once. How can i get it to do something like this:
connection = new MySqlConnection(connectionString);
Query = "SELECT status FROM Accounts WHERE username=#username";
connection = new MySqlConnection(connectionString);
MySqlCommand command = new MySqlCommand(Query, connection);
command.CommandType = System.Data.CommandType.Text;
command.Parameters.AddWithValue("#username", thedesiredusername);
connection.Open();
MySqlDataReader dataReader = command.ExecuteReader();
while (dataReader.Read())
{
//keep doing:
if (userstatus != dataReader.GetString("status"))
{
string userstatus = dataReader.GetString("status");
}
}
Thanks in advance!
If you can identify when the login state will change or can identify an event that's convenient to check (page load), event driven models are typically more efficient. If you don't have this luxury, then you're left polling the database every so often to see if the status has changed. Consider adding the filter to the database query rather than the client side code.
Typically, the database query is the most expensive part of the polling check. Trying to save a couple of processing cycles by checking if the new acquired matches the last check, isn't providing any sort of massive performance boost.
I am now using Devart.Data.MySql Package. this does exactly what i need.
I've ordered SQL Server from Somee. I want to use this SQL Server for my windows form. Somehow, i'm not sure, but whenever i execute the login query what i've found, it will have an unhandled exeption.
private void log_Click(object sender, EventArgs e)
{
SqlConnection con = new SqlConnection();
con.ConnectionString = "workstation id=wbhandler.mssql.somee.com;packet size=4096;user id=acc;pwd=pw;data source=wbhandler.mssql.somee.com;persist security info=False;initial catalog=wbhandler";
con.Open();
string felh = username.Text;
string jelsz = password.Text;
string query = "SELECT * FROM accounts WHERE account=#felhasznalo AND password=#jelszó";
SqlCommand cmd = new SqlCommand(query, con);
cmd.Parameters.Add(new SqlParameter("#felhasznalo", felh));
cmd.Parameters.Add(new SqlParameter("#jelszó", jelsz));
SqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows == true )
{
MessageBox.Show("Succes");
}
else
{
MessageBox.Show("Failed");
}
}
I thought that the adress is wrong, but then i found on the website the connection string, and now i don't really know.
I'm thinking what's the problem is.
I have 3 schemes in the sql:
dbo, acc, guest.
I first created a table in dbo, then in acc. Now in both of it. But it doesn't execute the SqlDataReader dr = cmd.ExecuteReader();, sadly. Like i said, it has unhandled exeption. Any solution? Any ideas?
(the acc scheme is an example what i created in somee, so it doesn't exist, it's fake)
I also tried this way:
using (var dr = cmd.ExecuteReader())
{
if (dr.HasRows)
{
MessageBox.Show("Sikeres Login!");
}
else
{
MessageBox.Show("Sikertelen Login");
}
}
The problem is always the ExecuteReader()
Try the SqlParameterCollection.AddWithValue Method instead:
cmd.Parameters.AddWithValue("#felhasznalo", felh);
cmd.Parameters.AddWithValue("#jelszó", jelsz);
I will also recommend that you use using statements on your SQL objects to ensure that the unmanaged resources they consume are freed when they are no longer needed. You can read more on the using statement from here.
Another thing that I can suggest is adding Charset=utf8; to your connection string.
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
I want to ask more to show data from SQL Server to WinForm using a datagrid.
I've been creating a datagrid and the stored procedure to show data is
ALTER PROC [dbo].[SP_GetData]
AS
SELECT nama , nim
FROM tabledata
and I've created the function to access the database and the stored procedure in C#
string Sp_Name = "dbo.SP_GetData";
SqlConnection SqlCon = new SqlConnection("Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBMahasiswa;Data Source=.");
SqlCon.Open();
SqlCommand SqlCom = new SqlCommand(Sp_Name , SqlCon);
SqlCom.CommandType = CommandType.StoredProcedure;
List<mahasiswaData> listMahasiswa = new List<mahasiswaData>();
using (SqlDataReader sqlDataReader = SqlCom.ExecuteReader())
{
if (sqlDataReader.HasRows)
{
while (sqlDataReader.Read())
{
mahasiswaData DataMhs = new mahasiswaData();
DataMhs.Nama = sqlDataReader["Name"].ToString();
DataMhs.Umur = Convert.ToInt32(sqlDataReader["Age"]);
listMahasiswa.Add(DataMhs);
}
}
}
SqlCon.Close();
return listMahasiswa;
and finally, in the show button I add this code
dgvmahasiswa.DataSource = new MahasiswaDB().LoadMahasiswa();
Could somebody tell me where the fault is or the alternatives one?
Thank You So Much! :D
Some things to think about:
At the moment, if your code runs into exceptions, you'll leave a
SqlConnection hanging around; you've used the using pattern for your
SqlDataReader; you should extend it to all of your disposable
objects.
You are swallowing exceptions; if your query fails, the connection
cannot be made, or something else happens, you'll never really know - your function will just return null.
Is it possible for name or age to be null? Age to be non-numeric?
There's no test for any unexpected values, which you'll also never
know about.
If you don't have any records, you'll return an empty list. Is this
desired? Or would you prefer to know there were no records?
You might prefer to look at something like this:
public List<mahasiswaData> GetData(){
List<mahasiswaData> gridData = new List<mahasiswaData>();
try{
using(SqlConnection conn = new SqlConnection("Integrated Security=SSPI;Persist Security Info=False;Initial Catalog=DBMahasiswa;Data Source=."))
{
using(SqlCommand command = new SqlCommand())
{
command.Connection = conn;
command.CommandType = CommandType.StoredProcedure;
command.Text = "dbo.SP_GetData";
using(SqlDataReader reader = command.ExecuteReader())
{
if(reader.HasRows){
while(reader.Read())
{
object rawName = reader.GetValue(reader.GetOrdinal("Name"));
object rawAge = reader.GetValue(reader.GetOrdinal("Age"));
if(rawName == DBNull.Value || rawAge == DBNull.Value)
{
//Use logging to indicate name or age is null and continue onto the next record
continue;
}
//Use the object intializer syntax to create a mahasiswaData object inline for simplicity
gridData.Add(new mahasiswaData()
{
Nama = Convert.ToString(rawName),
Umur = Convert.ToInt32(rawAge)
});
}
}
else{
//Use logging or similar to record that there are no rows. You may also want to raise an exception if this is important.
}
}
}
}
}
catch(Exception e)
{
//Use your favourite logging implementation here to record the error. Many projects use log4Net
throw; //Throw the error - display and explain to the end user or caller that something has gone wrong!
}
return gridData;
}
Note that if you are sure that age or name will never be null then you can simplify the middle section:
while (reader.Read())
{
//Use the object intializer syntax to create a mahasiswaData object inline for simplicity
gridData.Add(new mahasiswaData()
{
Nama = reader.GetString(reader.GetOrdinal("Name")),
Umur = reader.GetInt32(reader.GetOrdinal("Age"))
});
}
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");
}
}