"已经有一个开放的DataReader ......"似乎无法摆脱这个错误

时间:2015-09-24 16:50:40

标签: c# sql asp.net sitecore

所以我正在为Sitecore编写自定义成员资格提供程序,我的策略是将源代码下载到SQLMembershipProvider(sitecore已经使用过),然后只添加我的自定义逻辑。

我们想要的核心功能之一是能够存储密码历史记录,而我正在使用ChangePassword函数启动。

前几次我尝试了我的代码我没有任何问题,但现在即使在计算机重启后,尝试断开所有用户与数据库的连接,并重构我的代码以便它只使用一个SQLCommand和一个连接我无法获得摆脱这个错误。

我包含了更改密码功能的相关代码(我使用//我的代码添加的自定义代码 - 开始/结束)。有什么想法吗?

try
{
    SqlConnectionHolder recentpw_holder = null;
    SqlDataReader reader = null;
    SqlCommand tempcmd = null;
    try
    {
        recentpw_holder = SqlConnectionHelper.GetConnection(_sqlConnectionString, true);
        CheckSchemaVersion(recentpw_holder.Connection);

        //my code - Start
        tempcmd = new SqlCommand("SELECT * FROM dbo.PasswordHistory WHERE username='" + username + "' ORDER BY date_created", recentpw_holder.Connection);

        using (reader = tempcmd.ExecuteReader())
        {
            var passwordlist = new List<string>();
            while (reader.Read())
            {
                //get the list of passwords
                for (int i = 0; i < reader.FieldCount; i++)
                {
                    passwordlist.Add(reader.GetValue(i).ToString());
                }
            }

             //if there are more than 10 passwords stored in the database remove the oldest one
             if (passwordlist.Count > 10)
             {
                 tempcmd.CommandText = "DELETE * FROM dbo.PasswordHistory" +
                     "WHERE username='" + username + "'" +
                     "AND password='" + passwordlist.First()                                  + "'";

                  tempcmd.ExecuteNonQuery();
                  passwordlist.RemoveAt(0);
              }

              //check and see if that password has already been used, if so throw an error
              foreach (var p in passwordlist)
              {
                  if (p == pass)
                  {
                      throw new ArgumentException("Unable to create password. Password does not meet the history requirements of the domain.");
                   }
               }

                }

                //my code - end

                tempcmd.CommandText = "dbo.aspnet_Membership_SetPassword";

                tempcmd.CommandTimeout = CommandTimeout;
                tempcmd.CommandType = CommandType.StoredProcedure;
                tempcmd.Parameters.Add(CreateInputParam("@ApplicationName", SqlDbType.NVarChar, ApplicationName));
                tempcmd.Parameters.Add(CreateInputParam("@UserName", SqlDbType.NVarChar, username));
                tempcmd.Parameters.Add(CreateInputParam("@NewPassword", SqlDbType.NVarChar, pass));
                tempcmd.Parameters.Add(CreateInputParam("@PasswordSalt", SqlDbType.NVarChar, salt));
                tempcmd.Parameters.Add(CreateInputParam("@PasswordFormat", SqlDbType.Int, passwordFormat));
                tempcmd.Parameters.Add(CreateInputParam("@CurrentTimeUtc", SqlDbType.DateTime, DateTime.UtcNow));

                SqlParameter para = new SqlParameter("@ReturnValue", SqlDbType.Int);
                para.Direction = ParameterDirection.ReturnValue;
                tempcmd.Parameters.Add(para);

                tempcmd.ExecuteNonQuery();

                //my code pt 2 - start
                tempcmd.Parameters.Clear();
                tempcmd.CommandType = CommandType.Text;
                tempcmd.CommandText = "INSERT INTO dbo.PasswordHistory "
                                      + "(username, password, date_created) "
                                      + "VALUES ('" +
                                      username + "', '" +
                                      pass + "', '" +
                                      DateTime.UtcNow + "')";

                tempcmd.ExecuteNonQuery();
                //my code pt 2 - end


                status =  ( ( para.Value != null ) ? ( ( int )para.Value ) : -1 );

                if ( status != 0 )
                {
                    string errText = GetExceptionText( status );

                    if ( IsStatusDueToBadPassword( status ) )
                    {
                        throw new MembershipPasswordException( errText );
                    }
                    else
                    {
                        throw new ProviderException( errText );
                    }
                }

                return true;
            }
            finally
            {
                if (reader != null)
                {
                    reader.Close();
                    reader = null;
                }

                if( recentpw_holder != null )
                {
                    recentpw_holder.Close();
                    recentpw_holder = null;
                }
            }
        } catch {
            throw;
        }

1 个答案:

答案 0 :(得分:0)

一旦您不再需要,您需要处理该阅读器。试试这个:

            using (reader = tempcmd.ExecuteReader())
            {
                var passwordlist = new List<string>();
                while (reader.Read())
                {
                    //get the list of passwords
                    for (int i = 0; i < reader.FieldCount; i++)
                    {
                        passwordlist.Add(reader.GetValue(i).ToString());
                    }
                 }
            }

                //if there are more than 10 passwords stored in the database remove the oldest one
                if (passwordlist.Count > 10)
                {
                    tempcmd.CommandText = "DELETE * FROM dbo.PasswordHistory" +
                                                          "WHERE username='" + username + "'" +
                                                          "AND password='" + passwordlist.First()                                        + "'";

                    tempcmd.ExecuteNonQuery();
                    passwordlist.RemoveAt(0);
                }

                //check and see if that password has already been used, if so throw an error
                foreach (var p in passwordlist)
                {
                    if (p == pass)
                    {
                        throw new ArgumentException("Unable to create password. Password does not meet the history requirements of the domain.");
                    }
                }