【问题标题】:getting exception in creating a password change form在创建密码更改表单时出现异常
【发布时间】:2013-11-07 19:22:44
【问题描述】:

我正在创建密码更改表单。当我执行表单并填写文本框时,它会给出异常消息There is already and open DataReader associated with this command which must be closed first

他是我正在使用的代码:

private bool CompareStrings(string string1, string string2)
        {
            return String.Compare(string1, string2, true, System.Globalization.CultureInfo.InvariantCulture) == 0 ? true : false;
        }

    private void button1_Click(object sender, EventArgs e)
    {
        try
        {
            SqlConnection con1 = new SqlConnection();
            con1.ConnectionString = "data source=.;Initial catalog=inventory;Integrated Security=true";
            con1.Open();

            SqlCommand cmd = new SqlCommand("SELECT ISNULL(username, '') AS username, ISNULL(password,'') AS password FROM login WHERE username='" + textBox1.Text + "' and password='" + textBox2.Text + "'", con1);

            SqlDataReader dr = cmd.ExecuteReader();

            string userText = textBox1.Text;
            string passText = textBox2.Text;

            while (dr.Read())
            {
                if (this.CompareStrings(dr["username"].ToString(), userText) &&
                    this.CompareStrings(dr["password"].ToString(), passText))
                {
                    SqlCommand cmd2 = new SqlCommand("UPDATE login SET password='" + textBox3.Text + "'where username='" + textBox1.Text + "'", con1);
                    cmd2.ExecuteNonQuery();
                    MessageBox.Show("Password Changed Successfully");
                }
                else
                {
                    MessageBox.Show("Incorrect Old password");                        
                }

            }

            dr.Close();

            con1.Close();

        }
        catch (Exception ex)
        {
            MessageBox.Show(ex.Message);
        }

【问题讨论】:

    标签: c# sql-server exception


    【解决方案1】:

    当您打开 DataReader 时,连接只处理来自 DataReader 的请求。用于更新登录表的 SqlCommand 无法运行。

    除非你把它添加到你的连接字符串中

    MultipleActiveResultSets = True;
    

    Here you can find the reference to MARS

    还有here the words from MSDN 关于DataReader

    在使用 SqlDataReader 时,关联的 SqlConnection 是 忙于服务SqlDataReader,不能进行其他操作 在 SqlConnection 上执行而不是关闭它。情况就是这样 直到调用 SqlDataReader 的 Close 方法。例如, 在调用 Close 之前,您无法检索输出参数。

    作为旁注,但非常重要。不要使用字符串连接来构建 sql 命令。始终使用参数化查询

    string cmdText = "UPDATE login SET password=@pwd where username=@usr";
    using(SqlCommand cmd2 = new SqlCommand(cmdText, con1))
    {
        cmd2.Parameters.AddWithValue("@pwd", textBox3.Text);
        cmd2.Parameters.AddWithValue("@usr", textBox1.Text);
        cmd2.ExecuteNonQuery();    
    }
    

    参数化查询将避免Sql Injection 问题并让您简化命令文本。
    对于代码开头的 SELECT 查询也是如此。不要相信来自用户的输入

    您应该注意的另一个问题是在数据库中存储明文密码。从安全的角度来看,这被认为是一种非常糟糕的做法。您应该对密码应用哈希函数并存储结果。在检查密码是否正确时,您对用户输入重复哈希函数,并根据存储在数据库中的哈希密码检查结果

    【讨论】:

    • 感谢您提供有关查询的其他信息。我不知道这个事实。感谢您增加了我的知识和您提供的解决方案。
    • 能否请您提供一个链接,让我可以学习使用哈希函数,因为我不知道它...
    • This is one old question 涵盖了一些关于散列和加密的内容
    • This is instead a more advanced question 并回答有关密码哈希的问题
    【解决方案2】:

    SqlDataReader 在同一连接上打开时,您无法执行命令。您可以通过以下两种方式之一来更改您的代码:

    1. 创建第二个连接并在第二个连接上运行更新查询。

    2. 存储来自阅读器的数据,关闭阅读器,然后更新所有数据。在您的情况下,您可以使用 Username in (<yourlisthere>)

    3. 在一个更新查询中存储所有用户名以进行更新和更新

    【讨论】:

    • 它有效,但是当输入错误的密码时,它不会显示存储在“else”语句中的消息。
    • 您选择了哪种解决方案?
    • 嗯。没关系,因为if 中的登录仅取决于读者。以前有用吗?
    • noops 也没有。你能提供解决方案吗..?
    • 调试的时候,文本框和数据库中的值真的一样吗?
    猜你喜欢
    • 1970-01-01
    • 2016-05-03
    • 2019-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多