MessageBox showing unwanted result - c#

I'm new at this world of developing a software. So this may sound silly.
I'm working on developing a simple Login System at college, and I want to speed things up a little bit, my professor can be a tad, disorganized and it jeopardize the little time we have to learn a million things about programming.
I could get the program running and only opening the Main Form if the username and password are valid.
Before I researched and made a register button that will write data in my database, the message box was working properly.
But now, I cannot seem to make the message box show up saying if it is either, a successful login or if it is not.
My code is as following for the Login button:
private void VLogin_Click(object sender, EventArgs e)
{
try
{
string ConnectionString = "User ID=*****;Password=*******;" +
"Database=C:\\Users\\marqu_000\\Documents\\WindowsFormsApplication13\\Sistema.GDB;" +
"DataSource=localhost";
FbConnection addDetailsConnection = new FbConnection(ConnectionString);
addDetailsConnection.Open();
string SQLCommandText = "select * from LOGIN where USERNAME=#username and PASSWORD=#password";
FbCommand addDetailsCommand = new FbCommand(SQLCommandText, addDetailsConnection);
addDetailsCommand.Parameters.Add("#username", FbDbType.VarChar, 15).Value = userName.Text;
addDetailsCommand.Parameters.Add("#password", FbDbType.VarChar, 15).Value = userPassword.Text;
FbDataReader reader = addDetailsCommand.ExecuteReader();
while (reader.Read())
{
this.Visible = false;
MainWin MWin = new MainWin();
MWin.ShowDialog();
Application.Exit();
}
MessageBox.Show("Login Successful");
}
catch (Exception x)
{
MessageBox.Show("Invalid username or password");
MessageBox.Show(x.Message);
}
}
And this is my code for the register button:
private void registerUser_Click(object sender, EventArgs e)
{
try
{
string ConnectionString = "User ID=****;Password=****;" +
"Database=C:\\Users\\marqu_000\\Documents\\WindowsFormsApplication13\\Sistema.GDB;" +
"DataSource=localhost";
FbConnection addDetailsConnection = new FbConnection(ConnectionString);
addDetailsConnection.Open();
FbCommand SQLCommandTextInsert = new FbCommand("INSERT INTO LOGIN(USERNAME, PASSWORD, LEVEL) VALUES (#username,#password,#level)", addDetailsConnection);
SQLCommandTextInsert.Parameters.AddWithValue("username", registerUsername.Text);
SQLCommandTextInsert.Parameters.AddWithValue("password", registerPassword.Text);
SQLCommandTextInsert.Parameters.AddWithValue("level", registerLevel.Text);
SQLCommandTextInsert.ExecuteNonQuery();
MessageBox.Show("Registration completed!");
}
catch (FbException fbex)
{
//throw fbex;
MessageBox.Show("Invalid information, please verify!");
MessageBox.Show(fbex.Message);
}
}
If there is any good-for-nothing lines in there, and easiest ways to make those things, I would like to know.
I thank you all in advance for the help.
Marco.

ShowDialog is a blocking call, that means no code will run until that call completes. Which in this case is when your MWin closes. You'll need to display the success message before calling ShowDialog or call it from MWin.
Your Login failed message will only show when an exception occurs. I think if i read your code correctly if the reader returns no results (failed login) then you'll display "Login Succesful" and then doing nothing else.
You can use an if to determine if the database returned results and login failed is your else condition.

I finally made it!
I searched how to validate with a IF and could do it. This is how my code is now:
try
{
string ConnectionString = "User ID=*****;Password=*******;" +
"Database=C:\\Users\\marqu_000\\Documents\\WindowsFormsApplication13\\Sistema.GDB;" +
"DataSource=localhost";
FbConnection addDetailsConnection = new FbConnection(ConnectionString);
addDetailsConnection.Open();
string SQLCommandText = "select * from LOGIN where USERNAME=#username and PASSWORD=#password";
FbCommand addDetailsCommand = new FbCommand(SQLCommandText, addDetailsConnection);
addDetailsCommand.Parameters.Add("#username", FbDbType.VarChar, 15).Value = userName.Text;
addDetailsCommand.Parameters.Add("#password", FbDbType.VarChar, 15).Value = userPassword.Text;
FbDataReader reader = addDetailsCommand.ExecuteReader();
if (reader.Read())
{
this.Visible = false;
MessageBox.Show("Login Successful!");
MainWin MWin = new MainWin();
MWin.ShowDialog();
}
else
{
MessageBox.Show("Invalid username or password!");
}

Related

How to check if user is log in once enter a form using c# winform only, no asp.netc#

NO asp.net c# used
I need to know if user is login once he/she enter a form and if he/she is not login, he goes back to the login form. Everywhere I saw people use asp.net to achieve that but I want to know how to do it without using asp.net.
public DataTable Login(String Username, String Password)
{
server = "localhost";
database = "xxxx";
uid = "root";
password = "";
string MySQLConnectionString = $"datasource=127.0.0.1;port = 3306; SERVER={server}; DATABASE={database}; USERNAME={uid}; PASSWORD={password};sslmode=none";
MySqlConnection db_Conn = new MySqlConnection(MySQLConnectionString);
MySqlCommand cmd = new MySqlCommand();
db_Conn.ConnectionString = MySQLConnectionString;
string username_txtfield = username_txtbox.Text;
string pw_txtfield = password_txtbox.Text;
try
{
db_Conn.Open();
cmd.Connection = db_Conn;
cmd.CommandText = "SELECT count(*),user_id,person_username,role_id FROM user_tb " +
"WHERE person_username=#username " +
"AND user_password=#password";
cmd.Prepare();
cmd.Parameters.AddWithValue("#username", username_txtfield);
cmd.Parameters.AddWithValue("#password", pw_txtfield);
MySqlDataReader dr = cmd.ExecuteReader();
DataTable dt = new DataTable();
dt.Load(dr);
db_Conn.Close();
return dt;
}
catch (Exception ex)
{
throw ex;
}
}
login btn in my login form
private void button1_Click(object sender, EventArgs e)
{
//login();
try
{
DataTable result = Login(username_txtbox.Text, password_txtbox.Text);
if (result.Rows.Count == 1)
{
this.Hide();
string role = result.Rows[0]["role_id"].ToString();
switch (role)
{
case "3":
MessageBox.Show("User login successfully!");
user_form_page();
break;
case "1":
MessageBox.Show("Admin login successfully!");
//this.Hide();
Admin_page admin_form = new Admin_page();
admin_form.ShowDialog();
this.Close();
break;
}
}
else
{
MessageBox.Show("INVALID USERNAME OR PASSWORD");
}
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
Of course the ASP.Net identity services is a mature way of doing such a task but if you want you can have your own method of authentication but, you will need to implement many things.
Many of the stuff you need is actually based on the scenario you are implementing but the most basic thing you need is a static user that will be used via your methods to see if the user is already logged in or not. For example you can have:
public static class Authentication
{
public static User CurrentUser { get; private set; }
public static bool Login(User user)
{
if(user == null)
throw new ArgumentException("Invalid user","user");
CurrentUser = user;
}
}
This is just the most basic implementation of such a thing you can then check if CurrentUser is null or not and direct user to login page or show her the results.
As your requirements grow you will need to implement more stuff. A logout, a local or remote database for users, store currently logged in user in disk so that she doesn't need to login again after closing the app and many other things
Edit
Based on your new information you can add this line to your login button click like this:
if (result.Rows.Count == 1)
{
Authentication.Login(new User(result.Rows[0]["username"],result.Rows[0]["role_id"])
//The rest of code
}
I have also presumed that you have a class like:
class User
{
public string Name { get; }
public int RoleId { get; }
public User(string name, int roleId)
{
Name = name;
RoleId = roleId;
}
}
And then you have to check Authentication.CurrentUser against null in your user form or admin form constructors to ensure user is login you can use the information in Authentication.CurrentUser to show logged in user name or role or any other info.
I hope this helps you. If you need more info please say so.

WPF: Get closed window result in app.xaml.cs

Seemed to have this working before, just making a login system for my application. Got it checking a local database for users and creating an object with the user information. But when the user logs in the login window should close and display the main window.
As this happens I need to access data from the login window which I have done like so:
protected override void OnStartup(System.Windows.StartupEventArgs e)
{
if (!AreSettingsSet())
{
Window LoginWindow = new Views.LoginWindow();
LoginWindow.ShowDialog();
//Waits until closed.
//If the login form was closed properly, handle the user
if (LoginWindow.DialogResult == true)
{
MessageBox.Show("Logged in correctly!");
//Add the user to the list of logged users
User returned = LoginWindow.returnUser;
MessageBox.Show("First name:" + returned.FirstName);
LoggedUsers.Add(returned);
}
else
{
//Unexpected window close, possible Alt + F4, shutdown!
MessageBox.Show(Messages.UnexpectedClose);
this.Shutdown();
}
// Recheck the settings now that the login screen has been closed.
if (!AreSettingsSet())
{
}
}
this.MainWindow = new Views.Main();
this.MainWindow.Show();
}
Here is the LoginWindow:
//Give App access to user object outside of this form
public User returnUser
{
get
{
return user;
}
}
//Public user object, start empty
User user = new User();
//Check the login
private void doLogin(string email, string password)
{
//Connect to database
using (SqlConnection myConnection = new SqlConnection(Settings.ConnectionString))
{
//Try and open the connection
try
{
myConnection.Open();
}
catch (Exception)
{
//Unable to connect to database, just return
MessageBox.Show(Messages.UnableOpenConnection);
return;
}
string salt = null;
bool found = false;
using (SqlCommand command = new SqlCommand(Queries.GetSalt, myConnection))
{
//Fetch the salt for the entered email address
command.Parameters.Add(new SqlParameter("#email", email));
SqlDataReader reader = command.ExecuteReader();
//Read the data
reader.Read();
if (reader.HasRows)
{
salt = reader["salt"].ToString();
found = true;
}
//Close the reader
reader.Close();
}
if (found == true)
{
if (salt.Length == 32)
{
using (SqlCommand command = new SqlCommand(Queries.GetSingleUser, myConnection))
{
//Salt the password
string saltedPassword = Encryption.sha256(password + salt);
//Add paramaters
command.Parameters.Add(new SqlParameter("#email", email));
command.Parameters.Add(new SqlParameter("#password", saltedPassword));
SqlDataReader reader = command.ExecuteReader();
reader.Read();
if (reader.HasRows)
{
//Populate the login instance
user.ID = Convert.ToDecimal(reader["id"]);
user.FirstName = reader["firstname"].ToString();
user.LastName = reader["lastname"].ToString();
user.Email = reader["email"].ToString();
user.Permissions = Convert.ToInt16(reader["permissions"]);
//Close the reader
reader.Close();
//See if user has a thumbnail picture and save it's location
string thumbLoc = Directory.GetCurrentDirectory() +
"\\Users\\DisplayPictures\\" +
user.FirstName + user.LastName + ".png";
if (File.Exists(#thumbLoc))
{
user.ThumbLoc = thumbLoc;
}
else
{
user.ThumbLoc = Directory.GetCurrentDirectory() + "\\Users\\DisplayPictures\\user.png";
}
//Found user and created object, close this window safley
this.DialogResult = true;
this.Close();
}
else
{
//Unable to find a user
MessageBox.Show(Messages.NoUserFound);
return;
}
}
}
else
{
//Salt is the incorrect length
MessageBox.Show(Messages.InvalidSalt);
return;
}
}
else
{
MessageBox.Show(Messages.NoUserFound);
}
}
}
I'm getting an error here User returned = LoginWindow.returnUser; saying:
'System.Windows.Window' does not contain a definition for 'returnUser'
and no extension method 'returnUser' accepting a first argument of
type 'System.Windows.Window' could be found (are you missing a using
directive or an assembly reference?)
Please help me resolve this, and if i'm going about the login wrong please suggest changes!
That's because you declared the LoginWindow variable of type Window, instead of LoginWindow. LoginWindow has a returnUser property, but Window doesn't. Change the declaration to this:
Views.LoginWindow loginWindow = new Views.LoginWindow();
or just
var loginWindow = new Views.LoginWindow();
BTW, the convention in C# is to name local variables in camelCase, not PascalCase. For types and public members (methods, properties etc) you should use PascalCase. So the LoginWindow variable should be named loginWindow, and the returnUser property should be ReturnUser.

Progress bar not working on button click C# windows application

I want to synchronize my local and web database so i have written a stored procedure using linked server. My stored procedure executes fine and data synchronization is successful but the procedure takes around 7-10 minutes to get executed. The exact timing cannot be determined. So whenever the procedure runs on my windows application then the page seems as if it has become unresponsive though the process is still going on.
So i am having a "Data Sync" button on my page on click of which i want the progress bar to display the progress of the stored procedure. For the time being I am taking the average of last few execution timings to define the time duration for which the stored procedure runs. Now the problem is that when i click on the data sync button then the progress bar doesn't work. Kindly help me with this issue.
My code is as follows:-
namespace RMS
{
public partial class DataSync : Form
{
connection con = new connection();
SqlCommand cmd = new SqlCommand();
static int rowCount;
static int syncTime;
static int timeSlice;
public DataSync()
{
InitializeComponent();
}
private void btnDataSync_Click(object sender, EventArgs e)
{
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync();
try
{
con.GetConnectLive();
con.GetConnect();
if (con.CnLive.State == ConnectionState.Open)
{
MessageBox.Show("Connection to Live Server Successful!!!...Data Synchronisation may take several minutes so do not cancel the operation while in execution mode");
btnDataSync.Enabled = false;
btnDataSync.Text = "Please Wait...";
string Str = "RMS_LocalToLive";
cmd = new SqlCommand(Str, con.Cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 1200;
rowCount = cmd.ExecuteNonQuery();
if (rowCount > -1)
{
MessageBox.Show("Total no. of rows synchronised = " + rowCount);
btnDataSync.Text = "Success";
}
else
{
MessageBox.Show("Data Synchronisation couldn't be completed because of connection problem... Please try again!!!");
}
}
else
{
MessageBox.Show("Unable to connect to Live Server...Please check your internet connection and try again!!!");
}
con.GetDisConnect();
con.GetDisConnectLive();
}
catch (Exception ex)
{
MessageBox.Show("Please check your internet connection and try again!!!");
}
}
private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
try
{
con.GetConnect();
string Str = "RMS_DataSyncTime";
cmd = new SqlCommand(Str, con.Cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 1200;
syncTime = Convert.ToInt32(cmd.ExecuteScalar().ToString());
timeSlice = syncTime / 100;
con.GetDisConnect();
}
catch (Exception ex)
{
MessageBox.Show("Unable to retrieve last Data Synchronisation Timing");
}
for (int i = 1; i <= synctime; i=i+timeslice)
{
Thread.Sleep(timeslice);
// Report progress.
backgroundWorker1.ReportProgress(i);
}
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
// Change the value of the ProgressBar to the BackgroundWorker progress.
progressBar1.Value = e.ProgressPercentage;
// Set the text.
this.Text = e.ProgressPercentage.ToString() + "% Completed";
}
private void DataSync_Load(object sender, EventArgs e)
{
}
private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgse)
{
}
}
}
The main issue here is that, while you are executing your progress bar updates in the BackgroundWorker's thread, the ReportProgress() updates never make it to the UI thread, because you've blocked that thread with the main SQL operation.
Instead of doing that, you should do something more like this:
private void btnDataSync_Click(object sender, EventArgs e)
{
// Start the asynchronous operation.
backgroundWorker1.RunWorkerAsync();
btnDataSync.Enabled = false;
btnDataSync.Text = "Please Wait...";
bool success = false;
try
{
// Execute the query asynchronously
success = await Task.Run(() => ExecuteLocalToLive());
}
catch (Exception ex)
{
MessageBox.Show("Please check your internet connection and try again!!!");
}
btnDataSync.Enabled = true;
btnDataSync.Text = success ? "Success" : "Failure";
}
private bool ExecuteLocalToLive()
{
bool success = false;
con.GetConnectLive();
con.GetConnect();
if (con.CnLive.State == ConnectionState.Open)
{
MessageBox.Show("Connection to Live Server Successful!!!...Data Synchronisation may take several minutes so do not cancel the operation while in execution mode");
string Str = "RMS_LocalToLive";
cmd = new SqlCommand(Str, con.Cn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandTimeout = 1200;
rowCount = cmd.ExecuteNonQuery();
if (rowCount > -1)
{
MessageBox.Show("Total no. of rows synchronised = " + rowCount);
success = true;
}
else
{
MessageBox.Show("Data Synchronisation couldn't be completed because of connection problem... Please try again!!!");
}
}
else
{
MessageBox.Show("Unable to connect to Live Server...Please check your internet connection and try again!!!");
}
con.GetDisConnect();
con.GetDisConnectLive();
return success;
}
I have rearranged the code that handles the button state and text, so that it's still executed in the UI thread where it belongs, even though the method itself is not. You also never appeared to set the button back to the enabled state; it's not clear to me whether that was intentional or not, so I went ahead and added a line to do that.
Finally, I will strongly recommend you figure out a better way to report status to the user than the calls to MessageBox.Show() you have now. The biggest issue is that you don't even start doing any work until after the user dismisses the initial message, which immediately puts your progress bar out of sync with the actual work. But it's also better to keep all your UI in the UI thread, and to keep UI separate from non-UI logic (i.e. the SQL operation).

UDL File not found exception on Application Start

I have written the following code to implement common connection string so that all the forms use the connection string provided in Login Form of my application.The application works fine on my machine but when I run my application on any other machine I get the error "Connection to the server could not be established" ie it enters the catch block. even when the UDL file is available on the machine.Can anyone help me to rectify this.
Thanks
public void FrmLogin_Load(object sender, EventArgs e)
{
btncancel.CausesValidation = false;
try
{
string FileName = "Intellect_LeadMt.udl";
if (!File.Exists(FileName))
{
MessageBox.Show(FileName + " File is not available in current folder!");
//return;
this.Close();
}
string[] str = File.ReadAllLines(FileName);
con = new OleDbConnection(str[2]);
con.Open();
add = new AddModify_Lead(this);
foll = new Follow_Lead(this);
rem = new Reminder_Lead(this);
ContctAdd = new AddContact(this);
UtilityMaster = new UtilityMasters(this);
LeadManagerForm = new LeadManager(this);
Register = new FrmRegistration(this);
Mainform = new Form1(this);
Ld = new LoginDetails(this);
Ul = new UserLog(this);
Mc = new Modify_Client(this);
}
catch
{
MessageBox.Show("Connection to Database currently is unavailable!\n Please Check udl and start application once again.\n Sorry For the inconvenience", "Connection Error", MessageBoxButtons.OK, MessageBoxIcon.Information);
Application.Exit();
}
}

In winform button needs to be clicked twice for firing event

I have a buttton on the click event of which I am calling a function.I have set the accept button property to that button.But it is not firing the event on single click.
private void btnConnect_Click(object sender, EventArgs e)
{
try
{
//Function call for validating the textboxes entry
ValidateForm();
if(lblMessage.Text != string.Empty)
{
//Function call for binding the dropdown with all DB names
BindDBDropDown();
//Function call for binding the operation names in dropdown
SetOperationDropDown();
}
else
{
//Else give the error message to user
lblMessage.Text = "Invalid Credentials";
}
}
catch(Exception ex)
{
//All the exceptions are handled and written in the EventLog.
EventLog log = new EventLog("Application");
log.Source = "MFDBAnalyser";
log.WriteEntry(ex.Message);
}
}
public void BindDBDropDown()
{
SqlConnectionStringBuilder objConnectionString = new SqlConnectionStringBuilder();
objConnectionString.DataSource = txtHost.Text;
objConnectionString.UserID = txtUsername.Text;
objConnectionString.Password = txtPassword.Text;
SqlConnection sConnection = new SqlConnection(objConnectionString.ConnectionString);
//If connected then give this message to user
lblMessage.Visible = true;
lblMessage.Text = "You are connected to the SQL Server....";
try
{
//To Open the connection.
sConnection.Open();
//Query to select the list of databases.
string selectDatabaseNames = #"SELECT
NAME
FROM
[MASTER]..[SYSDATABASES]";
//Create the command object
SqlCommand sCommand = new SqlCommand(selectDatabaseNames, sConnection);
//Create the data set
DataSet sDataset = new DataSet("master..sysdatabases");
//Create the dataadapter object
SqlDataAdapter sDataAdapter = new SqlDataAdapter(selectDatabaseNames, sConnection);
sDataAdapter.TableMappings.Add("Table", "master..sysdatabases");
//Fill the dataset
sDataAdapter.Fill(sDataset);
//Bind the database names in combobox
DataViewManager dsv = sDataset.DefaultViewManager;
//Provides the master mapping between the sourcr table and system.data.datatable
cmbDatabases.DataSource = sDataset.Tables["master..sysdatabases"];
cmbDatabases.DisplayMember = "NAME";
cmbDatabases.ValueMember = ("NAME");
}
catch(Exception ex)
{
//All the exceptions are handled and written in the EventLog.
EventLog logException = new EventLog("Application");
logException.Source = "MFDBAnalyser";
logException.WriteEntry(ex.Message);
MessageBox.Show ("Login Failed!!", "Error Occured");
}
finally
{
//If connection is not closed then close the connection
if(sConnection.State != ConnectionState.Closed)
{
sConnection.Close();
}
}
}
Can anybody help me out??
Uh, on the first click, does lblMessage contain any text?
Because if not, the first time you run it, it will fail the conditional test and insert the string "Invalid Credentials" into the label. Then, the second time you run it, it will pass the conditional test and call the BindDBDropDown method as you're expecting.
Specifically, this section of your code:
if(lblMessage.Text != string.Empty)
{
//Function call for binding the dropdown with all DB names
BindDBDropDown();
//Function call for binding the operation names in dropdown
SetOperationDropDown();
}
else
{
//Else give the error message to user
lblMessage.Text = "Invalid Credentials";
}
I assume that you're either trying to check that the contents of a textbox where the user has entered their credentials are not empty, or that you want to make sure an error message is not currently displayed in lblMessage. Make sure that your code accurately reflects your intentions!

Categories