从C#连接到SQL Server时可能出现的错误是什么?

问题描述 投票:1回答:2

我在C#中创建了一个连接到SQL Server 2008的登录表单。数据读取器出错。我该怎么办?

这是我的决赛项目

SqlConnection con = new SqlConnection(@"Data Source=SAMSUNG-PC\SQLEXPRESS;Initial Catalog=LOGIN;Integrated Security=True");//this is my sql pc server name
SqlDataReader dr;

SqlCommand cmd = new SqlCommand("Select * from tbl_log where Username ='" + textBox1.Text + "' and Password = '", con);

con.Open();

cmd.Parameters.AddWithValue("un", textBox1.Text);
cmd.Parameters.AddWithValue("pw", textBox2.Text);

dr = cmd.ExecuteReader();//this is my problem//

if (dr.HasRows)//and this//
{
    menu menu = new menu();
    menu.Show();
    this.Hide();
}
else
{
    MessageBox.Show("error");
}
con.Close();

我希望这个输出:如果密码正确,请转到新表单,如果密码不正确,将出现消息框并说“错误”。

c# sql-server
2个回答
2
投票

这里有很多需要不同的东西。重要的是:

  • 正确的查询参数化(避免sql注入攻击)
  • 不要以纯文本格式存储密码。甚至不要在学习/练习代码中这样做!密码应使用信誉良好的算法进行单向散列(不要对它们进行加密)。
  • using阻止以避免在抛出异常时保持连接打开,以避免为数据库创建拒绝服务情况
  • 不要混用UI和数据库访问。实际上,即使我下面的代码也应该有两层,其中auth代码与数据库代码位于一个单独的类中

这样的事情要好得多:

public static class DB 
{
    private static string ConnectionString = @"Data Source=SAMSUNG-PC\SQLEXPRESS;Initial Catalog=LOGIN;Integrated Security=True";

    public static bool ValidateUserCredentials(string username, string password)
    {
                        //PwdHash column should be Char(60) (not VarChar, not NChar)
        string sql = "Select PwdHash from tbl_log where Username = @User";

        string hash = "";
        using (var cn = new SqlConnection(ConnectionString))
        using (var cmd = new SqlCommand(sql, cn))
        {
            //use actual column types and lengths from the database here
            // Do NOT use AddWithValue()!
            cmd.Parameters.Add("@User", SqlDbType.NVarChar, 20).Value = username;

            //keep the connection active for as brief a time as possible
            cn.Open();
            using (var rdr = cmd.ExecuteReader())
            {
                if (!rdr.Read()) return false;    
                hash = (string)rdr["PwdHash"];
            }
        }
        //based on this NuGet bcrypt library:
        //https://www.nuget.org/packages/BCrypt-Official/
        if (BCrypt.Net.BCrypt.Verify(password, hash)) return true;
        return false;
    }
}

然后你可以在用户界面中使用它,如下所示:

if (DB.ValidateUserCredentials(textBox1.Text, textBox2.Text))
{
    menu mu = new menu(); //can't give a variable the same name as it's type
    mu.Show();
    this.Hide();
}
else
{
    MessageBox.Show("error");
}

1
投票

在你从@Marc Gravell收到的所有正确评论之后......

要具体提到您的实际问题,您应该纠正

SqlCommand cmd = new SqlCommand("Select * from tbl_log where Username ='" + textBox1.Text + "' and Password = '", con);

//Here you're trying to add parameters that don't exist    
cmd.Parameters.AddWithValue("un", textBox1.Text);
cmd.Parameters.AddWithValue("pw", textBox2.Text);

SqlCommand cmd = new SqlCommand("Select * from tbl_log where Username = @UserName and Password = @Password", con);

cmd.Parameters.AddWithValue("@UserName", textBox1.Text);
cmd.Parameters.AddWithValue("@Password", textBox2.Text);

另外为了帮助你理解错误(因为它是对SQL的调用),你应该用try-catch包装代码

最后一句话,因为你是初学者...使用有意义的名字。尽量避免缩写,这是一个坏习惯。

© www.soinside.com 2019 - 2024. All rights reserved.