创建密码更改表单时出现异常
本文关键字:异常 表单 密码 创建 | 更新日期: 2023-09-27 18:37:15
我正在创建密码更改表单。 当我执行表单并填写文本框时,它会给出消息异常 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);
}
当SqlDataReader
在同一连接上打开时,不能执行命令。可以执行以下两项操作之一来更改代码:
-
创建第二个连接并在第二个连接上运行更新查询。
-
存储来自读取器的数据,关闭读取器,稍后更新所有数据。在您的情况下,您可以使用
Username in (<yourlisthere>)
存储所有用户名以更新和更新它们在一个更新查询中更新它们
当您打开 DataReader 时,连接仅处理来自 DataReader 的请求。用于更新登录表的 SqlCommand 无法运行。
除非将此添加到连接字符串
MultipleActiveResultSets = True;
在这里你可以找到对火星的参考
这是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 注入问题,并允许您简化命令文本。
代码开头的 SELECT 查询也是如此。不要相信来自用户的输入
您应该注意的另一个问题是在数据库中存储明文密码。从安全的角度来看,这被认为是一种非常糟糕的做法。您应该对密码应用哈希函数并存储结果。在检查正确的密码时,您在用户输入上重复哈希函数,并根据存储在数据库中的哈希密码检查结果