所以我正在为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;
}
答案 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.");
}
}