System.InvalidOperationException:未关闭连接。连接的当前状态是打开的

时间:2014-07-19 09:39:04

标签: c# asp.net-mvc webforms

我在不同的网站上搜索过但无法找到确切的解决方案。这是我的代码,请帮助我如何解决这个错误,我真的很感谢你。我在每个方法结束时都有紧密连接,但是我遇到了这个错误,当我发表评论时,另一个错误来了,#读取器关闭时无效尝试调用读取"

private void Count()
{
    int count;
    SqlDataReader reader = null;


    string selectedcmd = "SELECT COUNT(Review_rate) AS Review_count FROM Review WHERE (Paper_id = '" + Session["PaperID"] + "')";
    SqlCommand cmd = new SqlCommand(selectedcmd, dbcon);
    dbcon.Open();
    reader = cmd.ExecuteReader();
    while (reader.Read())
    {
        count = Convert.ToInt32(reader.GetInt32(0));


        if (count < 3)
        {
            Response.Redirect("Review_submit.aspx");
        }

        else
        {
            average();
        }
    }
    dbcon.Close();
}

private void average()
{
    int avg;
    SqlDataReader reader1 = null;


    string selectedValue = RadioButtonList1.SelectedValue;
    Response.Write(selectedValue);
    dbcon.Open();
    string selectedcmd = "SELECT AVG(Review_rate) AS AVG,COUNT(Review_rate) as Review_count  FROM  Review WHERE (Paper_id ='" + Session["PaperID"] + "') GROUP BY Paper_id HAVING (COUNT(Review_rate)>= 3)";
    SqlCommand cmd = new SqlCommand(selectedcmd, dbcon);

    reader1= cmd.ExecuteReader();
    while (reader1.Read())
    {
        avg = Convert.ToInt32(reader1.GetInt32(0));


        if (avg < 3)
        {
            if (reader1.HasRows)
            {
                SqlCommand cmd2 = new SqlCommand("SELECT [User].User_email FROM [User] INNER JOIN Paper ON [User].User_id = Paper.User_id WHERE ([User].User_id =Paper.User_id) AND (Paper.Paper_id ='" + Session["PaperID"] + "')", dbcon);
                // SqlCommand cmd1 = new SqlCommand("SELECT [User].User_email FROM [User] INNER JOIN Paper ON [User].User_id = Paper.User_id WHERE ([User].User_id ='2') AND (Paper.Paper_id ='2')", dbcon);
                string result = (string)cmd2.ExecuteScalar();

                //if (!string.IsNullOrEmpty(result))
                // {
                //   Label1.Text = result;
                // }

                StringBuilder bodyMsg = new StringBuilder();
                //email = Email.Text;
                bodyMsg.Append("Your paper is rejected");
                // bodyMsg.Append("<br /><br /><a href=http://localhost:7401/SendEmailConfirmationSample/Login.aspx?ID=" + email.ToString() + ">Activate Your Account</a>");
                bodyMsg.Append("<br />");
                bodyMsg.Append("<br />");
                bodyMsg.Append("<br />");
                // bodyMsg.AppendFormat("Registered Email: {0}", email);
                NetworkCredential loginInfo = new NetworkCredential("salmacms26@gmail.com", "salma@cms");
                MailMessage msg = new MailMessage();
                msg.From = new MailAddress("salmacms26@gmail.com");
                msg.To.Add(new MailAddress(result));
                msg.Subject = "Reviews Announcment";
                msg.Body = bodyMsg.ToString();
                msg.IsBodyHtml = true;

                SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
                client.EnableSsl = true;
                client.UseDefaultCredentials = false;
                client.Credentials = loginInfo;
                client.Send(msg);


                //Response.Redirect("~/Login.aspx");
            }
            else
            {
                if(reader1.HasRows)
                {
                    SqlCommand cmd2 = new SqlCommand("SELECT [User].User_email FROM [User] INNER JOIN Paper ON [User].User_id = Paper.User_id WHERE ([User].User_id =Paper.User_id) AND (Paper.Paper_id ='" + Session["PaperID"] + "')", dbcon);
                    // SqlCommand cmd1 = new SqlCommand("SELECT [User].User_email FROM [User] INNER JOIN Paper ON [User].User_id = Paper.User_id WHERE ([User].User_id ='2') AND (Paper.Paper_id ='2')", dbcon);
                    string result = (string)cmd2.ExecuteScalar();

                    if (!string.IsNullOrEmpty(result))
                    {
                        Label1.Text = result;
                    }

                    StringBuilder bodyMsg = new StringBuilder();
                    //email = Email.Text;
                    bodyMsg.Append("Your paper is accepted");
                    // bodyMsg.Append("<br /><br /><a href=http://localhost:7401/SendEmailConfirmationSample/Login.aspx?ID=" + email.ToString() + ">Activate Your Account</a>");
                    bodyMsg.Append("<br />");
                    bodyMsg.Append("<br />");
                    bodyMsg.Append("<br />");
                    // bodyMsg.AppendFormat("Registered Email: {0}", email);
                    NetworkCredential loginInfo = new NetworkCredential("salmacms26@gmail.com", "salma@cms");
                    MailMessage msg = new MailMessage();
                    msg.From = new MailAddress("salmacms26@gmail.com");
                    msg.To.Add(new MailAddress(result));
                    msg.Subject = "Reviews Announcment";
                    msg.Body = bodyMsg.ToString();
                    msg.IsBodyHtml = true;

                    SmtpClient client = new SmtpClient("smtp.gmail.com", 587);
                    client.EnableSsl = true;
                    client.UseDefaultCredentials = false;
                    client.Credentials = loginInfo;
                    client.Send(msg);


                    //Response.Redirect("~/Login.aspx");
                }
            }
        }
        dbcon.Close();
    }
}       

2 个答案:

答案 0 :(得分:1)

您的average方法尝试打开Count已打开的连接。

首先,您必须小心不要先关闭它而不先关闭它。

此外:

  • 您应该使用Close语句,而不是在连接上显式调用using,因为连接实现了IDisposable接口
  • 我将连接范围缩小为Count中的局部变量,并将其作为参数传递给average,如下所示:


private void Count()
{
    string selectedcmd = "SELECT COUNT(Review_rate) AS Review_count FROM Review WHERE (Paper_id = '" + Session["PaperID"] + "')";

    using(SqlConnection conn = new SqlConnection(connectionString) )
    using(SqlCommand command = new SqlCommand(selectedcmd, conn))
    {
        conn.Open();
        using(var reader = cmd.ExecuteReader())
        {
            while (reader.Read())
            {
                //more code
                average(conn);
            }
        }
    }
}

private void average(SqlConnection conn)
{
    //use the connection passed as an argument
}

如果发生异常,using语句将处理连接和命令甚至。如果发生异常,您当前的代码将不会关闭连接。

答案 1 :(得分:0)

不要使用全局变量来保持连接 开始使用using statement以确保正确关闭这些preciuos资源..

例如

private void Count()
{
    .....

    using(SqlConnection dbCon = new SqlConnection(connectionString))
    using(SqlCommand cmd = new SqlCommand(selectedcmd, dbcon))
    {
         dbcon.Open();
         using(SqlDataReader reader = cmd.ExecuteReader())
         {
              while (reader.Read())
              {
                  ......
              }
         } // Here the reader goes out of scope and it is closed and disposed
    }// Here the connection is closed and together with the command is disposed
}

这将删除您的问题,因为Using Statement将关闭并处理其块开头引用的每个一次性对象

作为旁注,与您的问题无关。字符串连接对于db(Sql Injection)的安全性可能非常危险。因此,会话[“ID”]值应使用parameterized approach

传递给您的查询