1、我们将该自定义MembershipProvider称为RemoteMembershipProvider。图2揭示了RemoteMembershipProvider实现的原理:RemoteMembershipProvider通过调用WCF服务MembershipService提供对成员资格所有功能的实现;MembershipService则通过调用Membership实现服务;最终的实现还是落在了SqlMembershipProvider这个原生的MembershipProvider上。clip_image004图2 RemoteMembershipProvider实现原理1、服务契约和服务实现
2、首先来看看MembershipService实现的服务契约的定义。由于MembershipService最终是为RemoteMembershipProvider这个自定义MembershipProvider服务的,所以服务操作的定义是基于MembershipProvider的API定义。MembershipProvider包含两种类型的成员:属性和方法,简单起见,我们可以为MembershipProvider每一个抽象方法定义一个匹配的服务操作;而对于所有属性,完全采用服务端(应用服务器)的MembershipProvider相关属性。在RemoteMembershipProvider初始化的
3、时候通过调用MembershipService获取所有服务端MembershipProvider的配置信息。为此,我们为MembershipProvider的所有属性定义了一个数据契约:MembershipConfigData。在PetShop中,MembershipConfigData和服务契约一起定义在Infrastructures.Service.Interface项目中。 1: using System.Runtime.Serialization; 2: using System.Web.Security; 3: namespace Artech.PetShop.Infrastruct
4、ures.Service.Interface 4: 5: DataContract(Namespace = 6: public class MembershipConfigData 7: 8: DataMember 9: public string ApplicationName 10: get; set; 11: 12: 13: public bool EnablePasswordReset 14: 15: 16: 17: public bool EnablePasswordRetrieval 18: 19: 20: 21: public int MaxInvalidPasswordAtte
5、mpts 22: 23: 24: 25: public int MinRequiredNonAlphanumericCharacters 26: 27: 28: 29: public int MinRequiredPasswordLength 30: 31: 32: 33: public int PasswordAttemptWindow 34: 35: 36: 37: public MembershipPasswordFormat PasswordFormat 38: 39: 40: 41: public string PasswordStrengthRegularExpression 42
6、: 43: 44: 45: public bool RequiresQuestionAndAnswer 46: 47: 48: 49: public bool RequiresUniqueEmail 50: 51: 52:在服务契约中,定义了一个额外的方法GetMembershipConfigData获取服务端MembershipProvider的所有配置信息,而对于服务操作的定义,则与MembershipProvider同名抽象方法相对应。 using System.ServiceModel; ServiceContract(Namespace= public interface IMemb
7、ershipService OperationContract bool ChangePassword(string username, string oldPassword, string newPassword); bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer); MembershipUser CreateUser(string username, string password, stri
8、ng email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status); bool DeleteUser(string username, bool deleteAllRelatedData); MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int tota
9、lRecords); MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords); MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords); int GetNumberOfUsersOnline(); string GetPassword(string username, string answer); O
10、perationContract(Name=GetUserByName) MembershipUser GetUser(string username, bool userIsOnline);GetUserByID MembershipUser GetUser(object providerUserKey, bool userIsOnline); string GetUserNameByEmail(string email); string ResetPassword(string username, string answer); bool UnlockUser(string userNam
11、e); void UpdateUser(MembershipUser user); bool ValidateUser(string username, string password); MembershipConfigData GetMembershipConfigData();服务的实现,则异常简单,我们须要做的仅仅是通过Membership.Provider获得当前的MembershipProvider,调用同名的属性或方法即可。MembershipService定义在Infrastructures.Service中,定义如下: using Artech.PetShop.Infrast
12、ructures.Service.Interface; namespace Artech.PetShop.Infrastructures.Service public class MembershipService : IMembershipService #region IMembershipService Members public bool ChangePassword(string username, string oldPassword, string newPassword) return Membership.Provider.ChangePassword(username,
13、oldPassword, newPassword); public bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer) return Membership.Provider.ChangePasswordQuestionAndAnswer(username, password, newPasswordQuestion, newPasswordAnswer); /其他成员 public Membersh
14、ipConfigData GetMembershipConfigData() return new MembershipConfigData ApplicationName = Membership.Provider.ApplicationName, EnablePasswordReset = Membership.Provider.EnablePasswordReset, EnablePasswordRetrieval = Membership.Provider.EnablePasswordRetrieval, MaxInvalidPasswordAttempts = Membership.
15、Provider.MaxInvalidPasswordAttempts, MinRequiredNonAlphanumericCharacters = Membership.Provider.MinRequiredNonAlphanumericCharacters, MinRequiredPasswordLength = Membership.Provider.MinRequiredPasswordLength, PasswordAttemptWindow = Membership.Provider.PasswordAttemptWindow, PasswordFormat = Members
16、hip.Provider.PasswordFormat, PasswordStrengthRegularExpression = Membership.Provider.PasswordStrengthRegularExpression, RequiresQuestionAndAnswer = Membership.Provider.RequiresQuestionAndAnswer, RequiresUniqueEmail = Membership.Provider.RequiresUniqueEmail ; #endregion2、RemoteMembershipProvider的实现由于
17、RemoteMembershipProvider完全通过调用WCF服务的方式提供对所有成员资格功能的实现,所以进行RemoteMembershipProvider配置时,配置相应的终结点就可以了。 configurationsystem.webmembership defaultProvider=RemoteProviderprovidersadd name= type=Artech.PetShop.Infrastructures.RemoteMembershipProvider,Artech.PetShop.Infrastructures, Version=1.0.0.0, Culture=
18、neutral, PublicKeyToken=null endpoint=membershipservice/providers/membership/system.websystem.serviceModelclientendpoint address=http:/localhost/PetShop/Infrastructures/MembershipService.svc behaviorConfiguration=petShopBehavior binding=ws2007HttpBinding contract=Artech.PetShop.Infrastructures.Servi
19、ce.Interface.IMembershipService name=/client/system.serviceModel/configuration在RemoteMembershipProvider中,通过Initialize方法获取配置的终结点名称并创建服务代理。通过该代理调用GetMembershipConfigData操作获取服务端MembershipProvider的配置信息,并对RemoteMembershipProvider进行初始化,RemoteMembershipProvider定义如下: using System.Collections.Specialized; us
20、ing System.Configuration; using System.Linq; using Artech.PetShop.Common; namespace Artech.PetShop.Infrastructures public class RemoteMembershipProvider : MembershipProvider private bool _enablePasswordReset; private bool _enablePasswordRetrieval; /其他字段成员 public IMembershipService MembershipProxy pr
21、ivate set; public override int MaxInvalidPasswordAttempts get return this._maxInvalidPasswordAttempts; /其他属性成员 public override void Initialize(string name, NameValueCollection config) if (!config.AllKeys.Contains(endpoint) throw new ConfigurationErrorsException(Missing the mandatory endpoint configu
22、raiton property.); this.MembershipProxy = ServiceProxyFactory.Create(config); base.Initialize(name, config); MembershipConfigData configData = this.MembershipProxy.GetMembershipConfigData(); this.ApplicationName = configData.ApplicationName; this._enablePasswordReset = configData.EnablePasswordReset; this._enablePasswordRetrieval = configData.EnablePasswordRetrieval; /.对于其他抽象方法的实现,仅仅须要通过上面创建的服务代理,调用相应的服务操作即可。注: 为了避免在服务操作调用后频繁地进行服务代理的关闭(Close)和终止(Abort)操作,我们采用基于AOP的方式实现服务的调用,将这些操作封装到一个自定义的RealProxy中,并通过ServiceProxyFactory创建该
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1