C# Additional information: Connection must be valid and open - c#

I have got some code: THE FULL
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using MySql.Data.MySqlClient;
namespace mysql
{
/// <summary>
/// Interaction logic for LoginPage.xaml
/// </summary>
public partial class LoginPage : Page
{
private string conn;
private MySqlConnection connect;
AdminPage ap = new AdminPage();
public LoginPage()
{
InitializeComponent();
}
private void db_connection()
{
try
{
conn = "Server=localhost;Database=student;Uid=root;Pwd=admin;";
connect = new MySqlConnection(conn);
connect.Open();
}
catch (MySqlException e)
{
throw;
}
}
private bool validate_login(string user, string pass)
{
db_connection();
MySqlCommand cmd = new MySqlCommand();
cmd.CommandText = "Select * from student.admins where username=#user and password=#pass";
cmd.Parameters.AddWithValue("#user", user);
cmd.Parameters.AddWithValue("#pass", pass);
cmd.Connection = connect;
MySqlDataReader login = cmd.ExecuteReader();
if (login.Read())
{
connect.Close();
return true;
}
else
{
connect.Close();
return false;
}
}
private void btn_login_Click(object sender, RoutedEventArgs e)
{
string user = txt_admin_name.Text;
string pass = txt_admin_passwd.Password;
if (user == "" || pass == "")
{
//MessageBox.Show("Empty Fields Detected ! Please fill up all the fields");
txt_errormessage.Text = "Empty Fields Detected! Please fill up all the fields!";
return;
}
bool r = validate_login(user, pass);
if (r)
{
//MessageBox.Show("Correct Login Credentials.\n You will be taken the Admin Page!");
this.NavigationService.Navigate(ap);
}
else
//MessageBox.Show("Incorrect Login Credentials");
txt_errormessage.Text = "Incorrect Login Credentials!";
}
}
}
So i need to some error handling: Check the server connection, and check existence of database. I would like to write MessageBox.
I tried but...
"Additional information: Connection must be valid and open."
Thanks in advance!

As soon as you validate the login, you are closing the connection:
if (login.Read())
{
connect.Close();
return true;
}
else
{
connect.Close();
return false;
}
Either leave the connection open, or reopen it. Most people leave it open for speed and simplicity.

When you need to use a connection to a database for every kind of task it is always a good practice to follow the pattern CREATE/OPEN/USE/CLOSE/DISPOSE
So your db_connection code should return the connection created and opened and never use a global variable to keep the connection instance.
private MySqlConnection db_connection()
{
try
{
conn = "Server=localhost;Database=student;Uid=root;Pwd=admin;";
MySqlConnection cnn = new MySqlConnection(conn);
cnn.Open();
return cnn;
}
catch (MySql.Data.MySqlClient.MySqlException ex)
{
switch (ex.Number)
{
case 0: MessageBox.Show("Cannot connect to server!"); break;
}
retur null;
}
}
Now the code that want to use your method could be written in a more resource friendly way
private bool validate_login(string user, string pass)
{
using(MySqlConnection cnn = db_connection())
using(MySqlCommand cmd = new cnn.CreateCommand())
{
cmd.CommandText = ".....";
cmd.Parameters.AddWithValue("#user", user);
cmd.Parameters.AddWithValue("#pass", pass);
using(MySqlDataReader login = cmd.ExecuteReader())
return login.HasRows;
}
}
No need to close explicitly the connection because the exit from the using block automatically closes the connection and disposes the instance freeing the resources kept by the connection both locally and on the server.
Of course, when you need to query again the database the same pattern should be used.

You need to tell your command about your connection object. Add the connection parameter to command
MySqlCommand cmd = new MySqlCommand(connect );

Related

How to connect the login button to my SQL Server database in C#?

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
using static System.Data.SqlClient.SqlConnection;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private SqlCommand cmd;
private Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text == "" && textBox2.Text == "")
{
MessageBox.Show("Please fill up all fields");
}
try
{
SqlCredential Librarypavilion = null;
SqlConnection SqlConnection = new SqlConnection("Data Source=DESKTOP-90R7QPM;Initial Catalog=", Librarypavilion, ";Integrated Security=True");
SqlCommand; cmd = new SqlCommand("select * from login where username = #username and password = #password");
cmd.Parameters.AddWithValue("#username", textBox1.Text);
cmd.Parameters.AddWithValue("#password", textBox2.Text);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
MessageBox.Show(" User is successfully logged in");
}
else
{
MessageBox.Show("Login unsuccessful");
}
}
catch (Exception ex)
{
MessageBox.Show("" + ex);
}
if (textBox2.Text == "")
{
MessageBox.Show("Please fill up password");
}
}
private void button2_Click(object sender, EventArgs e)
{
Form2 frm2 = new WindowsFormsApp1.Form2();
frm2.Show();
}
}
internal class sqlConnection
{
}
}
I'm quite just learning C# using vs. I am trying to connect the login button into the SQL I created. I can't run the program. it keeps giving me the error
SqlConnection does not contain a constructor that takes 3 arguments.
How do I solve it?
Your primary issue is that your connection string isn't right. It contains spurious ", which makes C# think you have three parameters. There are also other strange syntax errors.
There are other improvements:
On the first line, && should be ||. You also need to bail out if the fields are not filled.
SqlCredential is unnecessary, but you may want to put the connection string in a settings file.
SqlDataAdapter and DataTable are only necessary if you want to use data-binding to your UI. Otherwise you can use ExecuteReader and loop it whil (reader.Read())
In this case, you don't even need that, because you only check for existence of a row. So you can just use cmd.ExecuteScalar
You need to pass the connection object to the command, and you need to open the connection.
You need to dispose the connection and command with using.
Always pass the exact parameter type, using SqlDbType, along with the length, precision or scale if relevant.
Never store plain-text passwords. Salt-and-hash them, and compare the hashes on the server. Do not retrieve the stored hash to the client app.
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text == "" || textBox2.Text =="")
{
MessageBox.Show("Please fill up all fields");
return; //make sure to bail out
}
try
{
const string query = #"
select 1
from [login]
where username = #username
and password = #password;
";
using (var conn = new SqlConnection("Data Source=DESKTOP-90R7QPM;Initial Catalog=Librarypavilion;Integrated Security=True")
using (var cmd = new SqlCommand(query, conn)
{
cmd.Parameters.Add("#username", SqlDbType.NVarChar, 255).Value = textBox1.Text;
cmd.Parameters.Add("#password", SqlDbType.VarBinary, 128).Value = HashPassword(textBox1.Text, textBox2.Text);
conn.Open();
var exists = (cmd.ExecuteScalar() as int) == 1;
conn.Close();
if (exists)
{
MessageBox.Show(" User is Successfully login");
}
else
{
MessageBox.Show("unsuccessful");
}
}
}
catch(Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Consider using async and await to keep the UI alive.
private async void button1_Click(object sender, EventArgs e)
{
.....
await conn.OpenAsync();
var exists = ((await cmd.ExecuteScalarAsync()) as int) == 1;
conn.Close();

This code shows me that "CommandText has not been initialized"

I want to check ManagerUsername and ManagerEmail in the database and the display a messagebox to show the user with their password.But when I execute the code it shows me that:
"commandtext has not been initialized"
so I want to know how can I fix my code to display what I want. And also a way to improve my code to work more efficient
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace Cybertronics
{
public partial class passwordRecovery : Form
{
int pin = 0;
private int _failedAttempts = 0;
public passwordRecovery()
{
InitializeComponent();
}
private void passwordRecovery_Load(object sender, EventArgs e)
{
lblAttempt.Visible = false;
}
private void btnBackLogin_Click(object sender, EventArgs e)
{
loginFrm loginForm = new loginFrm();
this.Hide();
loginForm.Show();
}
private void btnSubmitEmail_Click(object sender, EventArgs e)
{
try
{
string emailAddress = txtEmail.Text;
string username = txtManagerUsername.Text;
string password = "ChangeMe";
CyberDatabase db = new CyberDatabase();
db.OpenConnection();
SqlCommand cmd = new SqlCommand();
SqlDataReader reader;
cmd.Parameters.AddWithValue("#ManagerUsername", username);
cmd.Parameters.AddWithValue("#ManagerEmail", emailAddress);
db.SetSqlCommand(cmd);
reader = db.Select();
cmd.CommandText = "SELECT ManagerUsername from tblManagers WHERE ManagerUsername = #ManagerUsername and ManagerEmail = #ManagerEmail";
db.SetSqlCommand(cmd);
reader = db.Select();
if (reader.HasRows)
{
reader.Read();
SqlCommand passwordUpdate = new SqlCommand();
passwordUpdate.CommandText = "UPDATE tblManagers SET ManagerPassword=#Password WHERE ManagerUsername=#ManagerUsername and ManagerEmail=#ManagerEmail";
db.SetSqlCommand(passwordUpdate);
MessageBox.Show("your new password is:" + password);
}
else
{
if (pin != 21)
{
_failedAttempts++;
MessageBox.Show("Wrong password or username fail to login. you have" + (3 - _failedAttempts) + " attempts more.", "EPIC FAIL", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
if (_failedAttempts == 3)
{
Application.Exit();
}
}
}
}
catch (SqlException sql)
{
CyberMethods.DisplayErrorMessage(sql.Message);//error message from cybermethods class for DB
}
catch (Exception exc)
{
CyberMethods.DisplayErrorMessage(exc.Message);//error message from cybermethods class
}
}
}
}
your code is very messy and untidy. It is very error prone. Check the below sample code for best practices.
using (connection)
using (SqlCommand command = new SqlCommand(
"SELECT ManagerUsername from tblManagers WHERE ManagerUsername = #ManagerUsername and ManagerEmail = #ManagerEmail",
connection))
{
connection.Open();
using (SqlDataReader reader = command.ExecuteReader())
{
if (reader.HasRows)
{
while (reader.Read())
{
Console.WriteLine("{0}\t{1}", reader.GetInt32(0),
reader.GetString(1));
}
}
else
{
Console.WriteLine("No rows found.");
}
}
}
you have multiple query statements. for the seperation of duties principles I suggest you to make 3 functions each seperate and call them respectively.
and It is wise to keep connection open then then close when all the operations finish.
For solving your error
before your first db.SetSqlCommand(cmd); just add your query statement with
cmd.CommandText = "select ....." ;

C# Mysql login error

I am working with C# (visual studio 2012 professional) and Mysql . I trying to create a login form, where a user needs to insert the username and password:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using MySql.Data.MySqlClient;
namespace Dark_Heresy
{
public partial class Login_Menu : Form
{
private MySqlConnection connection = new MySqlConnection();
public Login_Menu()
{
InitializeComponent();
TextPassword.PasswordChar = '*';
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void btn_Login_Click(object sender, EventArgs e)
{
try
{
string connectionString = "datasource = localhost; port = 3306; username = root; password = Mypass;";
using(MySqlConnection myConn = new MySqlConnection(connectionString))
using(MySqlCommand selectCommand = new MySqlCommand())
{
selectCommand.CommandText = ("SELECT COUNT(1) FROM dark_heresy.users WHERE users_=#User and password_=#Password;");
selectCommand.Connection = myConn;
selectCommand.Parameters.Add(new MySqlParameter("User", MySqlDbType.VarChar).Value = TextUserName.Text);
selectCommand.Parameters.Add(new MySqlParameter("Password", MySqlDbType.VarChar).Value = TextPassword.Text);
myConn.Open();
var ret = selectCommand.ExecuteScalar();
var count = Convert.ToInt32(ret);
if (count == 1)
{
this.Hide();
Menu mn = new Menu();
mn.ShowDialog();
}
else if (count > 1)
{
MessageBox.Show("Duplication of Username and Password... Access Denied");
}
else
{
MessageBox.Show("Incorrect Username and/or Password");
}
}
}
catch (Exception exp)
{
MessageBox.Show("Error: \r\n" + exp);
}
}
}
}
I don't get any syntax errors, but when i run this code i recieve this error:
MySql.Data.MySqlClient.MySqlException(0x80004005):
Only MySqlParameter objects may be stored at MySql.Data.MySqlClient.MySqlParameterCollection.Add(Object value)
at Dark_Heresy.Login_Menu.btn_Login_Click(Object sender, EventArgs e)
I know for security reason is it a better idea to use mysql.user table instead of dark_heresy.users table for user check, but right now is for testing purpose.
What is wrong with the code?
it says there is an error in line 39
I think your parameter syntax is wrong.
= operator returns the right side value also instead of just assigning. That's why;
new MySqlParameter("User", MySqlDbType.VarChar).Value = TextUserName.Text;
expression returns TextUserName.Text as a value and your parameter part will be like;
selectCommand.Parameters.Add(TextUserName.Text);
The right syntax seems;
selectCommand.Parameters.Add("#User", MySqlDbType.VarChar).Value = TextUserName.Text;
selectCommand.Parameters.Add("#Password", MySqlDbType.VarChar).Value = TextPassword.Text;
And please, don't store your passwords as a plain text.
Read: Best way to store password in database

Where am I supposed to call the method connection.Open() using C#?

Hi I am trying to get data from a database shown in a textbox. Doing this I have created three classes: Dal, Controller and TestForm. The thing is that I dont really know where to open the connection nor where to close it. This is what I've done.
In the class Dal I have:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Data.SqlClient;
using System.Data.Odbc;
namespace TestingDatabaseConnection
{
class Dal
{
private SqlConnection connection = new SqlConnection();
public SqlConnection GetConnection()
{
if (connection == null)
{
connection.ConnectionString = "Server=Mnemonics-DAT;Database=mem; Integrated Security = true;";
}
return connection;
}
public SqlDataReader GetData()
{
SqlDataReader sqlReads = null;
SqlCommand sqlCommand = new SqlCommand("select * from table_name", GetConnection());
sqlReads = sqlCommand.ExecuteReader();
return sqlReads;
}
}
}
In the class Controller I have:
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TestingDatabaseConnection
{
class Controller
{
private Dal dal = new Dal();
public SqlDataReader GetData()
{
return dal.GetData();
}
}
}
and finally in the form:
public partial class TestForm : Form
{
Controller controll;
public TestForm()
{
InitializeComponent();
controll = new Controller();
}
private void showBtn_Click(object sender, EventArgs e)
{
try
{
SqlDataReader sqlReader = controll.GetData();
while (sqlReader.Read())
{
infTxtBox.Text = sqlReader.ToString();
}
}
catch (Exception e1)
{
MessageBox.Show("Something is wrong: " + e1);
}
}
}
The message I get says "Something is wrong: ExecuteReader requires an open and available Connection. The connection's current state is closed.
What I have tried to do to solve the problem(in the class Dal):
Making a property that gets the connection value like this:
public SqlConnection Connect
{
get
{
return connection;
}
}
And then using it in the method GetData():
public SqlDataReader GetData()
{
SqlDataReader sqlReads = null;
try
{
//I call the method Open() here
Connect.Open();
SqlCommand sqlCommand = new SqlCommand("select * from table_name", GetConnection());
sqlReads = sqlCommand.ExecuteReader();
}
catch (Exception e)
{
Console.WriteLine("Error is: " + e);
}
finally
{
//and close it here
Connect.Close();
}
return sqlReads;
}
The error message I get now says: "Something is wrong: Invalid attempt to call Read when reader is closed"
While referring to the class TestForm.
Problem is here:
if (connection == null)
{
connection.ConnectionString = "Server=Mnemonics-DAT;Database=mem; Integrated Security = true;";
}
Your connection can't be null because you initializing it before calling GetConnection method.Instead check your connection string:
if(connection.ConnectionString == "")
{
connection.ConnectionString = "Server=Mnemonics-DAT;Database=mem; Integrated Security = true;";
}
Probably it would better if you use using statements,it will automatically Dispose your Connection object when it's job is done, just define a connection string variable then use:
string connString = "Server=Mnemonics-DAT;Database=mem; Integrated Security = true";
using(var conn = new SqlConnection(connString))
using(var sqlCommand = new SqlCommand("select * from table_name", conn))
{
conn.Open();
sqlReads = sqlCommand.ExecuteReader();
conn.Close();
}
Problem : in Dal class file you are not opening your connection object connection before reading the data.
Solution : You need to Open the SqlConnection object using Open() method before reading the data.
Try This:
public SqlDataReader GetData()
{
SqlDataReader sqlReads = null;
SqlCommand sqlCommand = new SqlCommand("select * from table_name", GetConnection());
connection.Open(); //Open your connection object here.
sqlReads = sqlCommand.ExecuteReader();
return sqlReads;
}
Its because you're trying to read your SqlDataReader on a closed connection.
Do not call connection.close() in your getData() method instead add a method to your Dal class
like so :
public void CloseConnection()
{
connect.close()
}
and then call your closeConnection method after looping trough your DataReader :
SqlDataReader sqlReader = controll.GetData();
while (sqlReader.Read())
{
infTxtBox.Text = sqlReader.ToString();
}
control.CloseConnection();

Response.Redirect Doesn't Work in my Windows Forms Application

My page does not redirect to the Page I have specified. While I am doing so it says The name "Response" does not exist in the current context
Please also help me with getting the register value in the database while doing the signup.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
namespace LoginSystem123
{
public partial class Login : Form
{
public Login()
{
InitializeComponent();
}
private void buttonLogin_Click(object sender, EventArgs e)
{
var myConnection = new SqlConnection();
myConnection.ConnectionString = #"Data Source=mukesh-PC\SQLEXPRESS;Initial Catalog=testDb;Integrated Security=True;Pooling=False";
var myCommand = new SqlCommand();
var cmd = "SELECT * FROM [User] Where [User].Email =" + "'" + textBoxEmail.Text + "'";
myCommand.CommandText = cmd;
myCommand.CommandType = CommandType.Text;
myCommand.Connection = myConnection;
myConnection.Open();
var myReader = myCommand.ExecuteReader();
bool isRegisteredUser = myReader.Read();
if (isRegisteredUser)
{
var PasswordFromDatabase = myReader.GetString(5);
if (textBoxPassword.Text == PasswordFromDatabase.TrimEnd())
{
MessageBox.Show("Successfully Logged on !");
}
else
{
MessageBox.Show("Invalid password. Try again");
}
}
else
{
MessageBox.Show("Invalid user");
}
}
/* private void buttonSignUp_Click(object sender, EventArgs e)
{
Response.Redirect("SignUp.cs");
}
*/
private void buttonSignUp_Click_1(object sender, EventArgs e)
{
Response.Redirect("SignUp.cs");
}
}
}
Response.Redirect is used to redirect to another page in an ASP website - nothing like this works in Windows Forms.
If SignUp.cs defines a Form, you can do something like this to show it:
var signup = new SignUp();
signup.ShowDialog();
If you let us know more about what you're trying to do, we can probably be a bit more helpful.
Response.Redirect only works for web applications, and it looks like you're coding for Windows application.
You should do this instead:
SignUp su = new SignUp();
su.Show();
this.Hide();

Categories