C# “登录”按钮读取sql数据库并确认输入到文本框中的值与所述sql数据库中的值将抛出错误

C# “登录”按钮读取sql数据库并确认输入到文本框中的值与所述sql数据库中的值将抛出错误,c#,sql-server,C#,Sql Server,我是一个试图创建一个登录页面的noob,用户在其中输入用户名和密码,该用户名和密码已经存在于连接到文本框/按钮/表单的sqldatabase中。下面的代码是我最好的尝试,但在调试时,它抛出catch,尽管输入的文本框值已在sql数据库中注册。如果需要任何其他信息,请询问 private bool compareStoD(string teststring1, string teststring2) { return String.Compare(teststring1,

我是一个试图创建一个登录页面的noob,用户在其中输入用户名和密码,该用户名和密码已经存在于连接到文本框/按钮/表单的sqldatabase中。下面的代码是我最好的尝试,但在调试时,它抛出catch,尽管输入的文本框值已在sql数据库中注册。如果需要任何其他信息,请询问

 private bool compareStoD(string teststring1, string teststring2)
    {
        return String.Compare(teststring1, teststring2, true, System.Globalization.CultureInfo.InvariantCulture) == 0 ? true : false;
    }    

 private void button1_Click_1(object sender, EventArgs e)
    {
        try
        {
            SqlConnection connection = new SqlConnection(@"Data Source=DESKTOP-P3JSE1C;Initial Catalog=logins;Integrated Security=True");
            connection.Open();
            SqlCommand checker = new SqlCommand("SELECT COUNT (*) from users WHERE username='" + textBox1.Text + "'AND pssword='" + textBox3.Text + "'", connection);
            SqlDataReader reader = checker.ExecuteReader();
            string usernameText = textBox1.Text;
            string psswordText = textBox3.Text;
            while (reader.Read())
            {
                if (this.compareStoD(reader["username"].ToString(), textBox1.Text) && // replace textbox1.Text with text string usernameText
                    this.compareStoD(reader["pssword"].ToString(), textBox3.Text))   //replace textbox3.Text with text string psswordText
                {
                    main wen = new main();
                    wen.Show();
                }
            }
            reader.Close();
            connection.Close();
        }
        catch
        {
            MessageBox.Show("Incorrect password or username.");
        }

    } 

它很可能引发异常,因为您的查询要求计数,但您正在读取读取器中不存在的列
username
password
。这是您的查询:

SELECT COUNT (*)
将其更改为:

SELECT username, password ...
另外,除非您希望每个精明的用户都能访问您的应用程序,否则请使用
SqlParameter
来避免


另一个建议

我不确定什么是
main
,我假设它是某个窗口,但我不会在您现在显示的位置显示它。尝试尽快关闭读卡器,然后显示窗口,如果用户通过了这样的身份验证

bool userIsAuthenticated = false;
if (reader.Read())
{
    // if a row was returned, it must be the row for the user you queried
    userIsAuthenticated = true;
}
reader.Close();
connection.Close();

// Now that the reader is closed, you can show the window so the reader does not stay
// open during the duration of the main window
if (userIsAuthenticated)
{
    main wen = new main();
    wen.Show();
}

它很可能引发异常,因为您的查询要求计数,但您正在读取读取器中不存在的列
username
password
。这是您的查询:

SELECT COUNT (*)
将其更改为:

SELECT username, password ...
另外,除非您希望每个精明的用户都能访问您的应用程序,否则请使用
SqlParameter
来避免


另一个建议

我不确定什么是
main
,我假设它是某个窗口,但我不会在您现在显示的位置显示它。尝试尽快关闭读卡器,然后显示窗口,如果用户通过了这样的身份验证

bool userIsAuthenticated = false;
if (reader.Read())
{
    // if a row was returned, it must be the row for the user you queried
    userIsAuthenticated = true;
}
reader.Close();
connection.Close();

// Now that the reader is closed, you can show the window so the reader does not stay
// open during the duration of the main window
if (userIsAuthenticated)
{
    main wen = new main();
    wen.Show();
}

如果要将行本身更改为选择用户名、密码而不是选择计数(*),则选择计数返回的是计数而不是行

如果要将行本身更改为选择用户名、密码而不是选择计数(*),则选择计数返回计数而不是行

您的代码正在做过多的工作。通过将UI中的用户名和密码值与表中的值进行比较,可以查询数据库。一旦从数据库中检索到值,您将再次比较UI中的值和数据库中的值。这是不必要的

只有当数据库中的值匹配时,查询才会返回值,因此您无需再次比较它们。因此,根本不需要方法
compareStoD

按钮1\u单击
可按以下方式更改,以简化操作

private void button1_Click_1(object sender, EventArgs e)
{
    try
    {
        SqlConnection connection = new SqlConnection(@"Data Source=DESKTOP-P3JSE1C;Initial Catalog=logins;Integrated Security=True");
        connection.Open();
        SqlCommand checker = new SqlCommand("SELECT COUNT (*) from users WHERE username=@userName AND pssword = @password", connection);
        checker.Parameters.Add(new SqlParameter("@userName", textBox1.Text));
        checker.Parameters.Add(new SqlParameter("@password", textBox3.Text));
        var count = Convert.ToInt32(checker.ExecuteScalar());
        connection.Close();
        if(count > 0)
        {
           main wen = new main();
           wen.Show();
        }
        else
        {
            MessageBox.Show("Incorrect password or username.");
        }
    }
    catch
    {
        MessageBox.Show("Incorrect password or username.");
    }
} 

您的代码正在完成过多的工作。通过将UI中的用户名和密码值与表中的值进行比较,可以查询数据库。一旦从数据库中检索到值,您将再次比较UI中的值和数据库中的值。这是不必要的

只有当数据库中的值匹配时,查询才会返回值,因此您无需再次比较它们。因此,根本不需要方法
compareStoD

按钮1\u单击
可按以下方式更改,以简化操作

private void button1_Click_1(object sender, EventArgs e)
{
    try
    {
        SqlConnection connection = new SqlConnection(@"Data Source=DESKTOP-P3JSE1C;Initial Catalog=logins;Integrated Security=True");
        connection.Open();
        SqlCommand checker = new SqlCommand("SELECT COUNT (*) from users WHERE username=@userName AND pssword = @password", connection);
        checker.Parameters.Add(new SqlParameter("@userName", textBox1.Text));
        checker.Parameters.Add(new SqlParameter("@password", textBox3.Text));
        var count = Convert.ToInt32(checker.ExecuteScalar());
        connection.Close();
        if(count > 0)
        {
           main wen = new main();
           wen.Show();
        }
        else
        {
            MessageBox.Show("Incorrect password or username.");
        }
    }
    catch
    {
        MessageBox.Show("Incorrect password or username.");
    }
} 

另外一个很好的做法是,在从Textbox提供值时,应该使用Textbox.Text.Trim(),这有助于消除开头和结尾的空格。这些空格可能会在后期产生问题。

另外一个好的做法是,在从Textbox提供值时,应该使用Textbox.Text.Trim(),这有助于消除开头和结尾的空格。这些空间可能会在后期产生问题。

您会遇到什么错误?您不应该使用这种方法从数据库获取数据,它容易受到sql注入的影响。您应该使用存储过程(推荐)或
sqlParameter
帮自己一个忙并注意异常。不仅如此,这也提出了问题。异常中包含大量信息。当您编写“抛出异常”时,这表明您没有花太多精力进行故障排除。这里还有另一个关于在SQL语句中使用参数的链接,帮助您提供与代码最接近的示例。您会遇到什么错误?您不应该使用此方法从数据库获取数据,它容易受到sql注入的攻击。您应该使用存储过程(推荐)或
sqlParameter
帮自己一个忙并注意异常。不仅如此,这也提出了问题。异常中包含大量信息。当您编写“抛出异常”时,它清楚地表明您没有花太多精力进行故障排除。这里还有一个关于在SQL语句中使用参数的链接,帮助您提供与代码最接近的示例。