专题八的上篇大致讨论了MemberRole中的Membership实现,对于运用Membership进行web开发足够,但是对于想更深入了解Membership实现机理的朋友那是远远不够的,这个专题我们更深入一下了解Membership。 其实MemberRole是一个非常好的资源包,借住Reflector这个优秀的工具,你可以对其进行代码分析。它无论是在组建的构架、代码的设计、数据库表的建立、存储过程的使用等都是非常优秀的,你是程序员也好构架师也罢,其中可以学习的真的很多很多,我在整个分析的过程中也深深受益。 由于MemberRole中的Membership只实现了对SQL Server的操Provider类,即SqlMembershipProvider类。因此我们从SqlMembershipProvider开始分析。Provider模型在上篇已经做过介绍,SqlMembershipProvider类继承了MembershipProvider,并实现其所有的抽象方法。在分析之前先看两个类:MembershipUser与MembershipUserCollection。 MembershipUser,先看看代码:(代码中省略的具体实现,只有方法与属性名称) public class MembershipUser { // Methods protected MembershipUser(); public MembershipUser(MembershipProvider provider, string name, object providerUserKey, string email, string passwordQuestion, string comment, bool isApproved, bool isLockedOut, DateTime creationDate, DateTime lastLoginDate, DateTime lastActivityDate, DateTime lastPasswordChangedDate, DateTime lastLockoutDate); public virtual bool ChangePassword(string oldPassword, string newPassword); public virtual bool ChangePasswordQuestionAndAnswer(string password, string newPasswordQuestion, string newPasswordAnswer); public virtual string GetPassword(); public virtual string GetPassword(string passwordAnswer); public virtual string ResetPassword(); public virtual string ResetPassword(string passwordAnswer); public override string ToString(); public virtual bool UnlockUser(); internal virtual void Update(); private void UpdateSelf(); // Properties public virtual string Comment { get; set; } public virtual DateTime CreationDate { get; } public virtual string Email { get; set; } public virtual bool IsApproved { get; set; } public virtual bool IsLockedOut { get; } public bool IsOnline { get; } public virtual DateTime LastActivityDate { get; set; } public virtual DateTime LastLockoutDate { get; } public virtual DateTime LastLoginDate { get; set; } public virtual DateTime LastPasswordChangedDate { get; } public virtual string PasswordQuestion { get; } public virtual MembershipProvider Provider { get; } public virtual object ProviderUserKey { get; } public virtual string UserName { get; } // Fields private string _Comment; private DateTime _CreationDate; private string _Email; private bool _IsApproved; private bool _IsLockedOut; private DateTime _LastActivityDate; private DateTime _LastLockoutDate; private DateTime _LastLoginDate; private DateTime _LastPasswordChangedDate; private string _PasswordQuestion; private MembershipProvider _Provider; private object _ProviderUserKey; private string _UserName; } 这是一个实体类,表示一个由Membership创建的User,该类中有这个User的一些基本状态,如该User的UserName、Email等,还有一些方法,如ChangePassword()、ResetPassword()等(如果你是初学者,还在为建立一个对象需要什么属性,包含什么方法发愁,那这就是你应该好好学的,这也是OOP最基本的要求)。 MembershipUserCollection,这是一个MembershipUser类的容器,用来存放MembershipUser列表,记得上次广州.net俱乐部聚会时,我的演讲中有朋友在提出CS是否使用自定义类来存储用户列表,其实在这里可以看到CS中使用的就是自定义的类而不是DataSet(我想在asp.net 2.0正式发布后这也不会改变),这样做主要是因为考虑到性能与灵活性。 好了,回到SqlMembershipProvider类上来,我们具体分析一个有代表性质的方法: public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{ string text3; MembershipUser user1; if (!SecUtility.ValidateParameter(ref password, true, true, false, 0x80)) { status = MembershipCreateStatus.InvalidPassword; return null; } string text1 = base.GenerateSalt(); string text2 = base.EncodePassword(password, (int) this._PasswordFormat, text1); if (text2.Length > 0x80) { status = MembershipCreateStatus.InvalidPassword; return null; } if (passwordAnswer != null) { passwordAnswer = passwordAnswer.Trim(); } if ((passwordAnswer != null) && (passwordAnswer.Length > 0)) { if (passwordAnswer.Length > 0x80) { status = MembershipCreateStatus.InvalidAnswer; return null; } text3 = base.EncodePassword(passwordAnswer.ToLower(CultureInfo.InvariantCulture), (int) this._PasswordFormat, text1); } else { text3 = passwordAnswer; } if (!SecUtility.ValidateParameter(ref text3, this.RequiresQuestionAndAnswer, this.RequiresQuestionAndAnswer, false, 0x80)) { status = MembershipCreateStatus.InvalidAnswer; return null; } if (!SecUtility.ValidateParameter(ref username, true, true, true, 0x100)) { status = MembershipCreateStatus.InvalidUserName; return null; } if (!SecUtility.ValidateParameter(ref email, this.RequiresUniqueEmail, this.RequiresUniqueEmail, false, 0x100)) { status = MembershipCreateStatus.InvalidEmail; return null; } if (!SecUtility.ValidateParameter(ref passwordQuestion, this.RequiresQuestionAndAnswer, this.RequiresQuestionAndAnswer, false, 0x100)) { status = MembershipCreateStatus.InvalidQuestion; return null; } if ((providerUserKey != null) && !(providerUserKey is Guid)) { status = MembershipCreateStatus.InvalidProviderUserKey; return null; } if (password.Length < this.MinRequiredPasswordLength) { status = MembershipCreateStatus.InvalidPassword; return null; } int num1 = 0; for (int num2 = 0; num2 < password.Length; num2++) { if (!char.IsLetterOrDigit(password, num2)) { num1++; } } if (num1 < this.MinRequiredNonAlphanumericCharacters) { status = MembershipCreateStatus.InvalidPassword; return null; } if ((this.PasswordStrengthRegularExpression.Length > 0) && !Regex.IsMatch(password, this.PasswordStrengthRegularExpression)) { status = MembershipCreateStatus.InvalidPassword; return null; } ValidatePasswordEventArgs args1 = new ValidatePasswordEventArgs(username, password, true); this.OnValidatingPassword(args1); if (args1.Cancel) { status = MembershipCreateStatus.InvalidPassword; return null; } try { SqlConnectionHolder holder1 = null; try { holder1 = SqlConnectionHelper.GetConnection(this._sqlConnectionString, true); this.CheckSchemaVersion(holder1.Connection); SqlCommand command1 = new SqlCommand("dbo.aspnet_Membership_CreateUser", holder1.Connection); command1.CommandTimeout = this.CommandTimeout; command1.CommandType = CommandType.StoredProcedure; command1.Parameters.Add(this.CreateInputParam("@ApplicationName", SqlDbType.NVarChar, this.ApplicationName)); command1.Parameters.Add(this.CreateInputParam("@UserName", SqlDbType.NVarChar, username)); command1.Parameters.Add(this.CreateInputParam("@Password", SqlDbType.NVarChar, text2)); command1.Parameters.Add(this.CreateInputParam("@PasswordSalt", SqlDbType.NVarChar, text1)); command1.Parameters.Add(this.CreateInputParam("@Email", SqlDbType.NVarChar, email)); command1.Parameters.Add(this.CreateInputParam("@PasswordQuestion", SqlDbType.NVarChar, passwordQuestion)); command1.Parameters.Add(this.CreateInputParam("@PasswordAnswer", SqlDbType.NVarChar, text3)); command1.Parameters.Add(this.CreateInputParam("@IsApproved", SqlDbType.Bit, isApproved)); command1.Parameters.Add(this.CreateInputParam("@UniqueEmail", SqlDbType.Int, this.RequiresUniqueEmail ? 1 : 0)); command1.Parameters.Add(this.CreateInputParam("@PasswordFormat", SqlDbType.Int, (int) this.PasswordFormat)); command1.Parameters.Add(this.GetTimeZoneAdjustmentParam()); SqlParameter parameter1 = this.CreateInputParam("@UserId", SqlDbType.UniqueIdentifier, providerUserKey); parameter1.Direction = ParameterDirection.InputOutput; command1.Parameters.Add(parameter1); parameter1 = new SqlParameter("@ReturnValue", SqlDbType.Int); parameter1.Direction = ParameterDirection.ReturnValue; command1.Parameters.Add(parameter1); object obj1 = command1.ExecuteScalar(); DateTime time1 = this.RoundToSeconds(DateTime.Now); if ((obj1 != null) && (obj1 is DateTime)) { time1 = (DateTime) obj1; } int num3 = (parameter1.Value != null) ? ((int) parameter1.Value) : -1; if ((num3 < 0) || (num3 > 11)) { num3 = 11; } status = (MembershipCreateStatus) num3; if (num3 != 0) { return null; } providerUserKey = new Guid(command1.Parameters["@UserId"].Value.ToString()); return new MembershipUser(this, username, providerUserKey, email, passwordQuestion, null, isApproved, false, time1, time1, time1, time1, new DateTime(0x6da, 1, 1)); } finally { if (holder1 != null) { holder1.Close(); holder1 = null; } } } catch { throw; } return user1; } <  
1/2 1 2 下一页 尾页 |