【问题标题】:using IF condition inside a while loop in C#在 C# 的 while 循环中使用 IF 条件
【发布时间】:2013-04-20 06:12:06
【问题描述】:

我的 C# 代码有问题。我在 C# 2010 中创建了一个登录表单。当我验证用户名时,我在 while 循环 中使用了一个 if-condition 但问题是,即使用户名和密码正确,它执行else-statement。请帮我解决这个问题。

这是我的代码:

private void btnlogin_Click(object sender, EventArgs e) {
    string connection=
        @"Data Source=.\SQLEXPRESS;" 
        +" AttachDbFilename=|DataDirectory|ResturantDB.mdf;"
        +" Integrated Security=True; User Instance=True";

    SqlConnection cn=new SqlConnection(connection);

    try {
        cn.Open();
    }
    catch(Exception) {
        // print the exception's message?
        MessageBox.Show("Connection to Database failed; check Connection!");
    }

    SqlCommand cmd=new SqlCommand("SELECT * FROM [Login]", cn);
    cmd.Connection=cn;
    SqlDataReader reader=null;
    reader=cmd.ExecuteReader();

    while(reader.Read()) {
        if(
            txtuser.Text==(reader["Username"].ToString())
            &&
            txtpass.Text==(reader["Password"].ToString())
            ) {
            //MessageBox.Show( "logged in!" );
            Home newhome=new Home();
            newhome.Show();
            this.Hide();
        }
        else {
            MessageBox.Show("Incorrect credentials!");
        }
    }
}

【问题讨论】:

  • 您的登录表中是否只有一行?
  • 首先:您似乎以纯文本形式存储密码。别! SO上有很多关于密码散列和加盐的问题。请仔细阅读。第二:您不想查询登录表中的 all 行。只是对应于给定Username 的那个。然后只检查一次。不要在这里使用循环。

标签: c# if-statement while-loop


【解决方案1】:

当在 if 条件中找到用户名时,您应该使用中断,例如

bool found = false;
while (reader.Read())
{   
  if (txtuser.Text == (reader["Username"].ToString()) && txtpass.Text == (reader["Password"].ToString()))
  {
    //MessageBox.Show("loged in!");
    Home newhome = new Home();
    newhome.Show();              
    this.Hide();
    found = true;
    break;
  }
}

if (!found)
    MessageBox.Show("Incorrect credentian..!");

您进入 else 块是因为如果任何登录不正确,则会出现消息框,并且在您的代码中有 n-1 种情况。

【讨论】:

  • 谢谢你hoffmanuel,它真的很有帮助,我现在做的很好,谢谢..!!
  • 不客气。但我建议不要像 Corak 提到的那样使用纯文本密码
【解决方案2】:

您正在检查 所有 用户是否具有相同的用户名和密码。您需要优化 SQL 以仅选择该一个用户。另外,为了您的用户,请阅读密码哈希。

【讨论】:

    【解决方案3】:

    因为它在一个循环中。

    创建一个布尔变量。在循环中更新其值(如果发现相同的用户名和密码)并根据其值在外部检查。

    这样做

    bool found;
    while (reader.Read())
    {
        if (txtuser.Text == (reader["Username"].ToString()) && 
            txtpass.Text == (reader["Password"].ToString()))
        {
            found = true;
            break;
        }                
    }
    if (found)
    {
        MessageBox.Show("loged in!");
        Home newhome = new Home();
        newhome.Show();
    
        this.Hide();
    }
    else
    {
        MessageBox.Show("Incorrect credentian..!");
    }
    

    【讨论】:

    • 如果偶然发现的第一个记录是具有正确用户名(和密码)的记录,这将起作用。最好是"SELECT * FROM [Login] WHERE Username = @Username"。然后cmd.Parameters.AddWithValue("@Username", txtuser.text)
    【解决方案4】:

    我会这样解决的:

    private void btnlogin_Click(object sender, EventArgs e)
    {
        string connection = @"Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|ResturantDB.mdf;Integrated Security=True;User Instance=True";
        SqlConnection cn = new SqlConnection(connection);
        try
        {
            cn.Open();
        }
        catch (Exception)
        {
            MessageBox.Show("Conncetion to Database faild check Connection !");
        }
    
        while (true)
        {
            SqlCommand cmd = new SqlCommand("SELECT [Password] FROM [Login] WHERE [Username] = '" + txtuser.Text + "'", cn);
            cmd.Connection = cn;
            SqlDataReader reader = null;
            reader = cmd.ExecuteReader();
    
            if (!reader.HasRows)
                MessageBox.Show("User does not exist. Please, try again.");
            else
            {
                //username should be unique, so only one row is possible to have
                reader.Read();
                if (txtpass.Text == (reader["Password"].ToString()))
                    {
                        //MessageBox.Show("loged in!");
                        Home newhome = new Home();
                        newhome.Show();
    
                        this.Hide();
                        return;
                    }
                else
                        MessageBox.Show("Incorrect credentian..! Try again.");
            }
        }
    }
    

    【讨论】:

    • 看看 cmets 到 @crapple 的回答。使用SqlParameter,正如@comecme 所说,如果一个Username 有多个Passwords,你可能会遇到问题。
    【解决方案5】:

    最简单安全的方法

     SqlCommand cmd = new SqlCommand("Select uname, pswd from [Login] where uname =@uname and pswd =@ps", conn);
            cmd.Parameters.Add(new SqlParameter("@uname", "username here"));
            cmd.Parameters.Add(new SqlParameter("@ps", "pasword here"));            
            SqlDataReader reader = cmd.ExecuteReader();
            if (reader.Read()) 
            {
                 //MessageBox.Show( "logged in!" );
                Home newhome = new Home();
                newhome.Show();
    
                this.Hide();
    
            }
            else
            {
                MessageBox.Show( "Incorrect credentials!" );
            } 
    

    【讨论】:

      【解决方案6】:

      无需循环查看您的案例记录 使用此查询,在查询中匹配用户名和密码:

      "SELECT * FROM [Login] where Username='" + txtuser.Text "' and password = '"  + txtpass.Text + "'"
      

      【讨论】:

      • 为了一切美好和神圣,请使用SqlParameter
      • 理论上一个用户可以有多个密码。
      • @comecme - 确实如此,但这不相关,因为对于登录,您只想知道是否存在至少一个有效登录提供的用户名和密码。如果有多个,但不是那个特定的一个,则登录失败。
      • @Corak 抱歉,我没有看到您还在查询中包含密码。只看到你包含了用户名。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      • 2019-10-01
      • 1970-01-01
      • 2011-12-03
      • 2012-02-14
      • 2019-11-07
      相关资源
      最近更新 更多