我的新用户有注册表单:
然后,它还有一个按钮:
单击按钮Register
时,我设置命令以检查电子邮件是否已存在。
它会检查值并能够在调试过程中找到值。
但是发生了一个错误
已经有一个与此命令关联的打开DataReader,必须先关闭它。
这是我的ASP.NET标记:
<div id="success" runat="server" class="alert alert-success" visible="false">
Account registration success!
<br />
Account sent for approval. Thank you.
</div>
<div id="emailavail" runat="server" class="alert alert-success" visible="false">
Email is Available.
</div>
<div id="error" runat="server" class="alert alert-danger" visible="false">
Email is already in use
<br />
Please choose another email / Login if already registered
</div>
<div class="form-group">
<br />
<label class="control-label col-lg-4">User Type</label>
<div class="col-lg-8">
<asp:Label ID="UserType" runat="server" class="form-control" text="Customer" required />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">Email</label>
<div class="col-lg-8">
<asp:TextBox ID="txtEmail" runat="server" class="form-control" type="email"
MaxLength="80" required />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">Password</label>
<div class="col-lg-8">
<asp:TextBox ID="txtPassword" runat="server" class="form-control" TextMode="Password" MaxLength="20" required />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">First Name</label>
<div class="col-lg-8">
<asp:TextBox ID="txtFN" runat="server" class="form-control" MaxLength="80" required />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">Last Name</label>
<div class="col-lg-8">
<asp:TextBox ID="txtLN" runat="server" class="form-control" MaxLength="50" required />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">Company Name</label>
<div class="col-lg-8">
<asp:TextBox ID="txtCName" runat="server" class="form-control" MaxLength="50" required />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">Street</label>
<div class="col-lg-8">
<asp:TextBox ID="txtStreet" runat="server" class="form-control" MaxLength="50" required />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">Municipality</label>
<div class="col-lg-8">
<asp:TextBox ID="txtMunicipality" runat="server" class="form-control" MaxLength="100" required />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">City</label>
<div class="col-lg-8">
<asp:TextBox ID="txtCity" runat="server" class="form-control" MaxLength="50" required />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">Company Phone</label>
<div class="col-lg-8">
<asp:TextBox ID="txtCPhone" runat="server" class="form-control" MaxLength="12" type="number" required />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-4">Mobile</label>
<div class="col-lg-8">
<asp:TextBox ID="txtMobile" runat="server" class="form-control" MaxLength="12" type="number" required />
</div>
</div>
</div>
<div class="col-lg-10">
<span class="pull-right">
<asp:Button ID="btnCancel" runat="server" class="btn" style="color:White" text="Cancel" PostBackUrl="~/Default.aspx" BackColor="Black" />
<asp:Button ID="btnRegister" runat="server" class="btn btn-success"
Text="Register" style="color:White" onclick="btnRegister_Click" />
</span>
</div>
以下是代码隐藏:
protected void btnRegister_Click(object sender, EventArgs e)
{
con.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "SELECT Email FROM Registration WHERE Email=@Email";
cmd.Parameters.AddWithValue("@Email", txtEmail.Text);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
error.Visible = true;
emailavail.Visible = false;
success.Visible = false;
con.Close();
}
else
{
cmd.Connection = con;
cmd.CommandText = "INSERT INTO Users VALUES (@TypeID, @Email, @Password, " +
"@FirstName, @LastName, @CompanyName, @Street, @Municipality, @City, @CompanyPhone, @Mobile, " +
"@Status, @DateAdded, @DateModified)";
cmd.Parameters.AddWithValue("@TypeID", "2");
cmd.Parameters.AddWithValue("@Email", txtEmail.Text);
cmd.Parameters.AddWithValue("@Password", Helper.CreateSHAHash(txtPassword.Text));
cmd.Parameters.AddWithValue("@FirstName", txtFN.Text);
cmd.Parameters.AddWithValue("@LastName", txtLN.Text);
cmd.Parameters.AddWithValue("@CompanyName", txtCName.Text);
cmd.Parameters.AddWithValue("@Street", txtStreet.Text);
cmd.Parameters.AddWithValue("@Municipality", txtMunicipality.Text);
cmd.Parameters.AddWithValue("@City", txtCity.Text);
cmd.Parameters.AddWithValue("@CompanyPhone", txtCPhone.Text);
cmd.Parameters.AddWithValue("@Mobile", txtMobile.Text);
cmd.Parameters.AddWithValue("@Status", "Pending");
cmd.Parameters.AddWithValue("@DateAdded", DateTime.Now);
cmd.Parameters.AddWithValue("@DateModified", DBNull.Value);
}
cmd.ExecuteNonQuery();
con.Close();
}
我确实尝试过:
selectedindexchanged
标签名称,因为它确实再次从用户中选择电子邮件。con.close
,因为正如我所研究的那样,它有一些事情要做。请帮忙给我几个小时。
提前谢谢!
我还是c#
的新手答案 0 :(得分:4)
让我们再次重新阅读您的异常消息:
已经与此命令相关联的打开DataReader 必须先关闭
您有几个选择。
您可以在con.Close()
行之后手动处理阅读器
dr.Dispose();
或者您可以使用using
语句自动处理您的阅读器(我推荐)。
using(SqlDataReader dr = cmd.ExecuteReader())
{
...
} // <-- On this line your dr will disposed
或者您可以为SqlCommand
语句创建新的INSERT
对象,例如;
cmd = new SqlCommand();
cmd.Connection = con;
...
同样:There is already an open DataReader associated with this Command which must be closed first
答案 1 :(得分:4)
虽然SonerGönül已经提供了适用于这种情况的解决方案,但我想提出另一个视角,使您的整个问题没有实际意义(答案也太长,无法发表评论)。
你在这里所做的是有益于学习目的,但你在这里重新发明轮子。 3种主要的基于Web的语言(PHP,Java和.NET)都具有灵活且经过验证的用户管理系统。
鉴于这是ASP.NET,我强烈建议您使用默认的ASP.NET成员资格提供程序。成员资格提供程序抽象出所有用户管理,因此您无需手动配置SQL命令。例如,我可以在代码中看到2个明显的缺陷:
如果您使用ASP.NET成员资格提供程序,则会解决这两个问题。
答案 2 :(得分:2)
这只是搞砸了很多层次
首先,DataReader没有任何意图
只需计算“SELECT count(*)FROM Registration WHERE Email = @ Email”
检查计数,如果0,则插入
然后关闭连接
cmd.CommandText = "SELECT count(*) FROM Registration WHERE Email=@Email";
cmd.Parameters.AddWithValue("@Email", txtEmail.Text);
if ((Int32)cmd.ExecuteScalar() > 0)
{
error.Visible = true;
emailavail.Visible = false;
success.Visible = false;
}
else
{
cmd.CommandText = "INSERT INTO Users VALUES (@TypeID, @Email, @Password, " +
"@FirstName, @LastName, @CompanyName, @Street, @Municipality, @City, " +
"@CompanyPhone, @Mobile, @Status, @DateAdded, @DateModified)";
cmd.Parameters.AddWithValue("@TypeID", "2");
cmd.Parameters.AddWithValue("@Email", txtEmail.Text);
cmd.Parameters.AddWithValue("@Password", Helper.CreateSHAHash(txtPassword.Text));
cmd.Parameters.AddWithValue("@FirstName", txtFN.Text);
cmd.Parameters.AddWithValue("@LastName", txtLN.Text);
cmd.Parameters.AddWithValue("@CompanyName", txtCName.Text);
cmd.Parameters.AddWithValue("@Street", txtStreet.Text);
cmd.Parameters.AddWithValue("@Municipality", txtMunicipality.Text);
cmd.Parameters.AddWithValue("@City", txtCity.Text);
cmd.Parameters.AddWithValue("@CompanyPhone", txtCPhone.Text);
cmd.Parameters.AddWithValue("@Mobile", txtMobile.Text);
cmd.Parameters.AddWithValue("@Status", "Pending");
cmd.Parameters.AddWithValue("@DateAdded", DateTime.Now);
cmd.Parameters.AddWithValue("@DateModified", DBNull.Value);
cmd.ExecuteNonQuery();
}
con.Close();
也可以在一次旅行中完成,但我不是积极的,可以使用参数
IF NOT EXISTS(SELECT ...);
BEGIN
INSERT INTO ...;
END;
答案 3 :(得分:0)
感谢@Soner @Frisbee的帮助和善意考虑
我所做的就是把它们分开,因为我已经想到了我得到的答案,当我回到相同的场景时,我更容易理解。
protected void btnRegister_Click(object sender, EventArgs e)
{
con.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "SELECT Email FROM Users WHERE Email=@Email";
cmd.Parameters.AddWithValue("@Email", txtEmail.Text);
SqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
error.Visible = true;
emailavail.Visible = false;
success.Visible = false;
con.Close();
}
else
{
success.Visible = false;
con.Close();
RegisterUser();
}
}
void RegisterUser()
{
con.Open();
SqlCommand cmd = new SqlCommand();
cmd.Connection = con;
cmd.CommandText = "INSERT INTO Users VALUES (@TypeID, @Email, @Password, " +
"@FirstName, @LastName, @CompanyName, @Street, @Municipality, @City, @CompanyPhone, @Mobile, " +
"@Status, @DateAdded, @DateModified)";
cmd.Parameters.AddWithValue("@TypeID", "2");
cmd.Parameters.AddWithValue("@Email", txtEmail.Text);
cmd.Parameters.AddWithValue("@Password", Helper.CreateSHAHash(txtPassword.Text));
cmd.Parameters.AddWithValue("@FirstName", txtFN.Text);
cmd.Parameters.AddWithValue("@LastName", txtLN.Text);
cmd.Parameters.AddWithValue("@CompanyName", txtCName.Text);
cmd.Parameters.AddWithValue("@Street", txtStreet.Text);
cmd.Parameters.AddWithValue("@Municipality", txtMunicipality.Text);
cmd.Parameters.AddWithValue("@City", txtCity.Text);
cmd.Parameters.AddWithValue("@CompanyPhone", txtCPhone.Text);
cmd.Parameters.AddWithValue("@Mobile", txtMobile.Text);
cmd.Parameters.AddWithValue("@Status", "Pending");
cmd.Parameters.AddWithValue("@DateAdded", DateTime.Now);
cmd.Parameters.AddWithValue("@DateModified", DBNull.Value);
cmd.ExecuteNonQuery();
con.Close();
}
再次感谢你们