|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
我觉得这个学习方法很重要。初学者应该跟我一样有同样一个毛病。那就是急于求成。很想就自己做出个小小的系统来。可真要动手,却又茫然而不知所措。为什么会这样呢?因为我们没有耐心去学习基础知识。写根本看不到什么效果的测试代码。serverMemberRole是一个在asp.net1.1下完成用户办理、脚色办理、用户特征信息存储(profile)等的一个组件,该组件被ASP.NET2.0Beta2所接纳,也就是ASP.NET2.0Beta2中所说的MembershipandRoles。假如你在asp.net1.1下接纳了MemberRole,那末你的web程序将会很简单的过渡到asp.net2.0,别的多个接纳MemberRole举行用户办理的web程序必要整应时也十分简单。我将分4个专题来剖析MemberRole,探究一下MemberRole究竟是怎样事情的,不管对CS的构架仍是对懂得asp.net2.0都长短常有匡助的。
CS中,使用该组件的4个部分:membership、roleManager、profile、anonymousIdentification的使用(全部MemberRole也这四部分功效)。
在剖析前,筹办必要一个工具:Reflector.exe,没有的伴侣google一下,下载它。
本次专题剖析membership,先看一下CS中Membership的设置文件(Web.Config中):
<membershipuserIsOnlineTimeWindow="15">
<providers>
<add
name="CommunityServerSqlProvider"
type="Openlab.AutoRegister.CSAutoBlogGalleryMembershipProvider,Openlab.CSAddOns"
connectionStringName="SiteSqlServer"
enablePasswordRetrieval="false"
enablePasswordReset="true"
requiresQuestionAndAnswer="false"
requiresUniqueEmail="true"
passwordFormat="Hashed"
applicationName="dev"
description="StoresandretrievesmembershipdatafromthelocalMicrosoftSQLServerdatabase"
autoCreateBlog="false"
defaultBlogGroupID="3"
autoCreateGallery="false"
defaultGalleryGroupID="2"
maxInvalidPasswordAttempts="999"
passwordAttemptWindow="999"
minRequiredPasswordLength="4"
minRequiredNonalphanumericCharacters="0"
/>
</providers>
</membership>
userIsOnlineTimeWindow:这是一个数值,用来盘算在线用户的数目,比方:15,就暗示假如用户在15分钟后不举动(收回Http哀求)CS体系将视该用户不在线。
Name:称号
type:类的名字空间与地点的程序汇合
connectionStringName:数据库毗连字符串节点的key。经由过程这个key就能够找到毗连数据库的用户名与暗码
enablePasswordRetrieval:是不是翻开取回奥密功效
enablePasswordReset:是不是翻开奥密从头设功效
requiresQuestionAndAnswer:注册时是不是必要填写Question与Answer
requiresUniqueEmail:注册时是不是Email独一
passwordFormat:暗码的加密格局
applicationName:利用该membership使用程序的称号
description:形貌信息
以下4个参数是CCS中增加的,目标是给注册用户主动守旧相册和博客
autoCreateBlog:是不是当用户注册时主动为该用户创建一个Blog
defaultBlogGroupID:默许的创建blog的分组ID
autoCreateGallery:是不是当用户注册时主动为该用户创建一个相册
defaultGalleryGroupID:默许的创建相册的分组ID
用Reflector.exe翻开MemberRole.dll,你能够看到以下的内容:
再翻开Microsoft.ScalableHosting.Configuration节点
此次我们只存眷两个类MembershipConfig、MembershipConfigHandler。MembershipConfigHandler完成了IConfigurationSectionHandler接口。也就是说,CS启动后假如挪用ConfigurationSettings.GetConfig("memberrolesprototype/membership"),体系将会主动的挪用MembershipConfigHandler中的Create办法把web.config中memberrolesprototype/membership的设置内容读进举行处置。先看以下Create做了些甚么:
publicvirtualobjectCreate(objectparent,objectconfigContextObj,XmlNodesection)
{
MembershipConfigconfig1=newMembershipConfig(parentasMembershipConfig);
intnum1=-1;
ConfigUtils.GetAndRemovePositiveIntegerAttribute(section,"userIsOnlineTimeWindow",refnum1);
if(num1>0)
{
config1.UserIsOnlineTimeWindow=num1;
}
stringtext1=null;
ConfigUtils.GetAndRemoveStringAttribute(section,"hashAlgorithm",reftext1);
if((text1!=null)&&(text1.Length>0))
{
config1.HashAlgorithmType=text1;
}
ConfigUtils.CheckForUnrecognizedAttributes(section);
MembershipProviderprovider1=null;
foreach(XmlNodenode1insection.ChildNodes)
{
if(node1.NodeType!=XmlNodeType.Element)
{
continue;
}
if(node1.Name!="providers")
{
thrownewConfigurationException("Unrecognizedtag:"+node1.Name,node1);
}
foreach(XmlNodenode2innode1.ChildNodes)
{
if(node2.NodeType==XmlNodeType.Element)
{
if(node2.Name!="add")
{
thrownewConfigurationException("Unrecognizedtag:"+node2.Name,node2);
}
if(provider1!=null)
{
thrownewConfigurationException("Onlyoneprovidercanbeconfigured",node2);
}
stringtext2=null;
stringtext3=null;
ConfigUtils.GetAndRemoveRequiredNonEmptyStringAttribute(node2,"name",reftext2);
ConfigUtils.GetAndRemoveRequiredNonEmptyStringAttribute(node2,"type",reftext3);
NameValueCollectioncollection1=newNameValueCollection();
foreach(XmlAttributeattribute1innode2.Attributes)
{
if((attribute1.Name!=null)&&(attribute1.Name.Length>0))
{
collection1.Add(attribute1.Name,attribute1.Value);
}
}
provider1=(MembershipProvider)Activator.CreateInstance(Type.GetType(text3,true));
provider1.Initialize(text2,collection1);
config1.Provider=provider1;
}
}
}
returnconfig1;
}
代码有点长,实在这里就是把web.config上面membership节点的设置信息读进,举行初始化,然后经由过程GetType与Activator.CreateInstance办法反射后实例化一个MembershipProvider。
MembershipProvider又是甚么,持续看看:
publicabstractclassMembershipProvider:ProviderBase
{
//Events
publiceventMembershipValidatePasswordEventHandlerValidatingPassword;
//Methods
protectedMembershipProvider();
publicabstractboolChangePassword(stringusername,stringoldPassword,stringnewPassword);
publicabstractboolChangePasswordQuestionAndAnswer(stringusername,stringpassword,stringnewPasswordQuestion,stringnewPasswordAnswer);
publicabstractMembershipUserCreateUser(stringusername,stringpassword,stringemail,stringpasswordQuestion,stringpasswordAnswer,boolisApproved,objectproviderUserKey,outMembershipCreateStatusstatus);
protectedvirtualbyte[]DecryptPassword(byte[]encodedPassword);
publicabstractboolDeleteUser(stringusername,booldeleteAllRelatedData);
internalstringEncodePassword(stringpass,intpasswordFormat,stringsalt);
protectedvirtualbyte[]EncryptPassword(byte[]password);
publicabstractMembershipUserCollectionFindUsersByEmail(stringemailToMatch,intpageIndex,intpageSize,outinttotalRecords);
publicabstractMembershipUserCollectionFindUsersByName(stringusernameToMatch,intpageIndex,intpageSize,outinttotalRecords);
internalstringGenerateSalt();
publicabstractMembershipUserCollectionGetAllUsers(intpageIndex,intpageSize,outinttotalRecords);
publicabstractintGetNumberOfUsersOnline();
publicabstractstringGetPassword(stringusername,stringanswer);
publicabstractMembershipUserGetUser(objectproviderUserKey,booluserIsOnline);
publicabstractMembershipUserGetUser(stringusername,booluserIsOnline);
publicabstractstringGetUserNameByEmail(stringemail);
protectedvirtualvoidOnValidatingPassword(ValidatePasswordEventArgse);
publicabstractstringResetPassword(stringusername,stringanswer);
internalstringUnEncodePassword(stringpass,intpasswordFormat);
publicabstractboolUnlockUser(stringuserName);
publicabstractvoidUpdateUser(MembershipUseruser);
publicabstractboolValidateUser(stringusername,stringpassword);
//Properties
publicabstractstringApplicationName{get;set;}
publicabstractboolEnablePasswordReset{get;}
publicabstractboolEnablePasswordRetrieval{get;}
publicabstractintMaxInvalidPasswordAttempts{get;}
publicabstractintMinRequiredNonAlphanumericCharacters{get;}
publicabstractintMinRequiredPasswordLength{get;}
publicabstractintPasswordAttemptWindow{get;}
publicabstractMembershipPasswordFormatPasswordFormat{get;}
publicabstractstringPasswordStrengthRegularExpression{get;}
publicabstractboolRequiresQuestionAndAnswer{get;}
publicabstractboolRequiresUniqueEmail{get;}
//Fields
privateMembershipValidatePasswordEventHandler_EventHandler;
privateconstintSALT_SIZE_IN_BYTES=0x10;
}
本来MembershipProvider是完成承继了ProviderBase的一个类,实在ProviderBase并没有甚么,看看代码
publicabstractclassProviderBase
{
//Methods
protectedProviderBase();
publicvirtualvoidInitialize(stringname,NameValueCollectionconfig);
//Properties
publicvirtualstringDescription{get;}
publicvirtualstringName{get;}
//Fields
privatestring_Description;
privatebool_Initialized;
privatestring_name;
}
ProviderBase仅仅只是回护了两个虚属性的类,设置这个类只是一种计划形式,没有出格的用处。我们把重点会合到MembershipProvider上,MembershipProvider类是Provider构架的一种表现情势,Provider构架经常用到对数据库的会见上,完成多半据库,同时也能够很好的断绝数据层与营业层的代码有益于合作开辟。详细完成是如许的,先把要操纵数据库的办法笼统出来,独自的放进一个abstract类,比方:MembershipProvider,然后经由过程承继,把这些笼统的办法全体的完成出来,比方:SqlMembershipProvider。如许有甚么优点呢?关于三层构架的web使用程序来讲,两头的营业逻辑层挪用操纵数据库的办法是从MembershipProvider,关于该层来讲它其实不体贴该笼统层是怎样被承继后完成笼统办法的。它只体贴笼统层中是不是有它想要的办法。假如能了解到这里,嘿嘿,我们的时机就来了,由于这断绝了详细的数据库操纵完成,更进一步说就是断绝了利用何种数据库。再从团队合作思索,假定你的MembershipProvider界说的完美后,承继MembershipProvider完成SQLServer操纵的SqlMembershipProvider类中的办法不管怎样改动,都不会影响别的职员在营业逻辑层的开辟。听起来这类体例仿佛很美,可是要完成如许的功效还必要一个关头的手艺,那就是反射,以是我们看到在设置的字段里有如许的字节:。
type="Openlab.AutoRegister.CSAutoBlogGalleryMembershipProvider,Openlab.CSAddOns"
这就是为了经由过程反射找到MembershipProvider详细办法完成的类而做的筹办。
注:因为剖析的代码来历于宝玉的CCS,在CCS中为了完成注册后能主动守旧博客与相册又承继了SqlMembershipProvider类,重写了几个办法(关头是个中的Initialize与CreateUser办法)。
只需你承继MembershipProvider类,对个中的笼统办法举行完成,不管你是完成对Access的操纵,仍是别的数据库,都是没有成绩的。在asp.net2.0beta2中的Membership已供应access与sqlserver两种数据库操纵完成。不外MemberRole.dll程序会合只完成了SqlMembershipProvider,也就是对SQLServer的操纵。
Membership是一个没有暗示层的使用组件,它包括了逻辑层与数据操纵层,数据层我在这个专题中就未几做注释,他的完成是在SqlMembershipProvider类中,你能够经由过程Reflector.exe渐渐研讨。下面的笔墨说过,完成Provider形式后营业逻辑层对数据层详细完成就不体贴了,在MemberRole.dll中的Membership,它把一切的这些逻辑用一个类包装起来,那就是Membership类:
关于援用MemberRole.dll完成Membership功效的webapp(DNN,CS就是典范)来讲,只需做符合的设置以后就能够间接利用了。
比方,要创建一个用户只需挪用Membership.CreateUser的静态办法,就能够完成(Membership会依据外部的办法和详细的数据库操纵,把用户信息写进数据库)。
关于利用Membership来开辟webapp的程序员来讲,完整能够不用要懂得这些细节,asp2.0beta2就没有供应如许的时机,MS只需求你会用就能够了,不外很光荣的是CS给我们供应了如许的一个时机,懂得这些操纵的本色(包含URLRewrite等功效也是一样,这些功效都能够在asp2.0beta2中间接利用,而不要构架怎样代码)。
这个专题只是大抵的解说了Membership,下一个专题,我们将更深切的往看看Membership的数据层的操纵完成和数据库表的计划(包含存储历程)。
对于new隐藏成员的作用,往往是出于使用了一个第三方类库,而你又无法获得这个类库的源代码,当你继承这个类库的某个类时,你需要重新实现其中的一个方法,而又需要与父类中的函数使用同样的函数,这是就需要在自定义的子类中把那个同名函数(或成员)加上new标记,从而隐藏父类中同名的成员。 |
|