我很难尝试解决它,并尝试了很多次,但仍然无法正常工作。在这种情况下,我有一个包含用户名和密码的登录表单。我有一个用于创建用户的数据库,用户的类型为admin和employee。我想要发生的是获取用户名和用户类型,并将其传递给另一种形式的标签。
这是我的代码
private static int count = 0;
private void btn_login_Click(object sender, EventArgs e)
{
using (var con = SQLConnection.GetConnection())
{
var selectCommand = new SqlCommand("Select * from Users_Profile where Username= @Username and Password= @Password", con);
selectCommand.Parameters.Add("@Username", SqlDbType.VarChar, 50).Value = txt_username.Text;
selectCommand.Parameters.Add("@Password", SqlDbType.VarChar, 50).Value = txt_password.Text;
SqlDataReader dataReader;
dataReader = selectCommand.ExecuteReader();
var loginSuccess = false;
while (dataReader.Read())
{
loginSuccess = true;
}
if (string.IsNullOrEmpty(txt_username.Text) || string.IsNullOrEmpty(txt_password.Text))
{
MetroMessageBox.Show(this, "Please input the Required Fields", "System Message:", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
else
{
if (loginSuccess)
{
count = 0;
MetroMessageBox.Show(this, "Login Successful", "System Message:", MessageBoxButtons.OK, MessageBoxIcon.Information);
this.Hide();
var obj = new MainForm(this);
obj.Closed += (s, args) => this.Close();
obj.Show();
}
else
{
count += 1;
if (count == 3)
{
MetroMessageBox.Show(this, "You have exceeded maximum login attempts, Please wait 10 seconds", "System Message:", MessageBoxButtons.OK, MessageBoxIcon.Stop);
txt_username.Enabled = false;
txt_password.Enabled = false;
btn_login.Enabled = false;
LoginAttempstimeOut.Start();
}
else
{
MetroMessageBox.Show(this, "Invalid Username/Password", "System Message:", MessageBoxButtons.OK, MessageBoxIcon.Stop);
}
}
}
}
}
private void LoginAttempstimeOut_Tick(object sender, EventArgs e)
{
LoginAttempstimeOut.Stop();
txt_username.Enabled = true;
txt_password.Enabled = true;
btn_login.Enabled = true;
count = 0;
}
答案 0 :(得分:0)
我同意匿名者的回答,但我相信您可以做一些事情来清理代码。
首先,为什么要在验证要传递的值之前查询数据库?首先从文本框中检查值,然后如果有值,请进行数据库调用。
第二。我将所有逻辑封装在一个单独的方法中,该方法返回适当的值,并从_Click()方法调用它。
private static int count = 0;
private void btn_login_Click(object sender, EventArgs e)
{
if (string.IsNullOrEmpty(txt_username.Text) || string.IsNullOrEmpty(txt_password.Text))
{
MetroMessageBox.Show(this, "Please input the Required Fields", "System Message:", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
}
else
{
string Results = CheckLogin(txt_username.Text, txt_password.Text)
//** code to handle results from db query **//
if (Results.Equals("Invalid"))
{
// handle bad password
count++;
}
else
{
// handle good password
}
}
}
private string CheckLogin(string User, string Pass)
{
string returnstring = "Invalid";
using (var con = SQLConnection.GetConnection())
{
var selectCommand = new SqlCommand("Select * from Users_Profile where Username= @Username and Password= @Password", con);
selectCommand.Parameters.AddWithValue("@Username", User);
selectCommand.Parameters.AddWithValue("@Password", Pass);
SqlDataReader dataReader;
dataReader = selectCommand.ExecuteReader();
var loginSuccess = false;
while (dataReader.Read())
{
loginSuccess = true;
returnstring = dataReader["Usertype"].ToString();
}
return returnstring;
}
我对自己的代码非常了解,因此我什至可以将好/坏密码尝试的处理也放在单独的方法中。似乎需要做很多额外的工作,但它遵循以下原则:将您的方法/函数保持尽可能小巧和简洁,并且只在这些方法中做一件事。
此外,还要增加以下内容::)切勿在生产代码中使用“ SELECT *”!与以往任何时候一样。
另一件事:如果您有权访问SQL Server创建存储过程,则整个SQL命令应位于返回适当值的存储过程中。
我知道您会在网上发现数百万个不使用存储过程的示例。那并不意味着是正确的。 :)使用存储过程有很多充分的理由,这是Microsoft的建议(至少以前是这样)。