我必须重用使用旧成员资格提供程序创建的旧数据库,即使用“dbo.aspnet_Users”这样的名称创建表。 我可以用
创建用户MembershipUser createdUser =
Membership.CreateUser("UserName", "Password", "UserName@email.com",
"Password Question", "Password Answer", true, out status);
但是当我尝试验证用户时
Membership.ValidateUser("UserName", "Password")
结果我总是假的。
使用Reflector我发现我从System.Web.Security.Membership
类调用此方法:
public static bool ValidateUser(string username, string password)
{
return Provider.ValidateUser(username, password);
}
在调试器中,我看到用户名和密码都有各自的值,在我进入Provider.ValidateUser(用户名,密码)之后;我到了System.Web.Security.SqlMembershipProvider.ValidateUser
:
public override bool ValidateUser(string username, string password)
{
if ((SecUtility.ValidateParameter(ref username, true, true, true, 0x100) && SecUtility.ValidateParameter(ref password, true, true, false, 0x80)) && this.CheckPassword(username, password, true, true))
{
PerfCounters.IncrementCounter(AppPerfCounter.MEMBER_SUCCESS);
WebBaseEvent.RaiseSystemEvent(null, 0xfa2, username);
return true;
}
PerfCounters.IncrementCounter(AppPerfCounter.MEMBER_FAIL);
WebBaseEvent.RaiseSystemEvent(null, 0xfa6, username);
return false;
}
但ValidateUser的方法参数密码现在为null,而username不为null。 我做错了吗?
upd:添加了捕获屏幕的视频,显示错误http://youtu.be/N9rcNonGZTI
upd 2:我决定尝试反射来调用
private bool CheckPassword(string username, string password, bool updateLastLoginActivityDate, bool failIfNotApproved, out string salt, out int passwordFormat)
来自System.Web.Security.SqlMembershipProvider类的方法
var provider = (SqlMembershipProvider) Membership.Provider;
var provider =(SqlMembershipProvider)Membership.Provider;
MethodInfo mInfoMethod = typeof(SqlMembershipProvider).GetMethod(
"CheckPassword",
BindingFlags.Instance | BindingFlags.NonPublic,
Type.DefaultBinder,
new[] { typeof(string), typeof(string), typeof(bool), typeof(bool), typeof(string).MakeByRefType(), typeof(int).MakeByRefType() }, null);
string str1 = null;
int num1 = 0;
var args = new object[] {"UserName", "Password", true, true, str1, num1};
var res = mInfoMethod.Invoke(provider, args);
我正在调用System.Web.Security.SqlMembershipProvider.CheckPassword的方法如下所示:
private bool CheckPassword(string username, string password, bool updateLastLoginActivityDate, bool failIfNotApproved, out string salt, out int passwordFormat)
{
SqlConnectionHolder connection = null;
string str;
int num;
int num2;
int num3;
bool flag2;
DateTime time;
DateTime time2;
this.GetPasswordWithFormat(username, updateLastLoginActivityDate, out num, out str, out passwordFormat, out salt, out num2, out num3, out flag2, out time, out time2);
if (num != 0)
{
return false;
}
if (!flag2 && failIfNotApproved)
{
return false;
}
string str2 = this.EncodePassword(password, passwordFormat, salt);
bool objValue = str.Equals(str2);
if ((objValue && (num2 == 0)) && (num3 == 0))
{
return true;
}
try
{
try
{
connection = SqlConnectionHelper.GetConnection(this._sqlConnectionString, true);
this.CheckSchemaVersion(connection.Connection);
SqlCommand command = new SqlCommand("dbo.aspnet_Membership_UpdateUserInfo", connection.Connection);
DateTime utcNow = DateTime.UtcNow;
command.CommandTimeout = this.CommandTimeout;
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(this.CreateInputParam("@ApplicationName", SqlDbType.NVarChar, this.ApplicationName));
command.Parameters.Add(this.CreateInputParam("@UserName", SqlDbType.NVarChar, username));
command.Parameters.Add(this.CreateInputParam("@IsPasswordCorrect", SqlDbType.Bit, objValue));
command.Parameters.Add(this.CreateInputParam("@UpdateLastLoginActivityDate", SqlDbType.Bit, updateLastLoginActivityDate));
command.Parameters.Add(this.CreateInputParam("@MaxInvalidPasswordAttempts", SqlDbType.Int, this.MaxInvalidPasswordAttempts));
command.Parameters.Add(this.CreateInputParam("@PasswordAttemptWindow", SqlDbType.Int, this.PasswordAttemptWindow));
command.Parameters.Add(this.CreateInputParam("@CurrentTimeUtc", SqlDbType.DateTime, utcNow));
command.Parameters.Add(this.CreateInputParam("@LastLoginDate", SqlDbType.DateTime, objValue ? utcNow : time));
command.Parameters.Add(this.CreateInputParam("@LastActivityDate", SqlDbType.DateTime, objValue ? utcNow : time2));
SqlParameter parameter = new SqlParameter("@ReturnValue", SqlDbType.Int)
{
Direction = ParameterDirection.ReturnValue
};
command.Parameters.Add(parameter);
command.ExecuteNonQuery();
num = (parameter.Value != null) ? ((int)parameter.Value) : -1;
}
finally
{
if (connection != null)
{
connection.Close();
connection = null;
}
}
}
catch
{
throw;
}
return objValue;
}
奇怪的是所有方法的输入参数都已设置,除了密码,它再次为空。