国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁(yè) > 開發(fā) > 綜合 > 正文

Community Server專題八:MemberRole之Membership

2024-07-21 02:29:27
字體:
來(lái)源:轉(zhuǎn)載
供稿:網(wǎng)友

memberrole是一個(gè)在asp.net 1.1下實(shí)現(xiàn)用戶管理、角色管理、用戶特性信息存儲(chǔ)(profile)等的一個(gè)組件,該組件被asp.net 2.0 beta 2所采用,也就是asp.net 2.0 beta 2中所說(shuō)的membership and roles。如果你在asp.net 1.1下采用了memberrole,那么你的web程序?qū)?huì)很容易的過(guò)渡到asp.net 2.0,另外多個(gè)采取memberrole進(jìn)行用戶管理的web程序需要整合時(shí)也非常容易。我將分4個(gè)專題來(lái)分析memberrole,探索一下memberrole到底是如何工作的,無(wú)論對(duì)cs的構(gòu)架還是對(duì)了解asp.net 2.0都是非常有幫助的。

cs中,運(yùn)用該組件的4個(gè)部分:membership、rolemanager、profile、anonymousidentification的運(yùn)用(整個(gè)memberrole也這四部分功能)。

在分析前,準(zhǔn)備需要一個(gè)工具:reflector.exe,沒(méi)有的朋友google一下,下載它。

本次專題分析membership,先看一下cs中membership的配置文件(web.config中):

<membership userisonlinetimewindow="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="stores and retrieves membership data from the local microsoft sql server database"

                       autocreateblog="false"

                       defaultbloggroupid="3"

                       autocreategallery="false"

                       defaultgallerygroupid="2"

                       maxinvalidpasswordattempts = "999"

                       passwordattemptwindow = "999"

                       minrequiredpasswordlength = "4"

                       minrequirednonalphanumericcharacters = "0"

                   />

              </providers>

</membership>

userisonlinetimewindow:這是一個(gè)數(shù)值,用來(lái)計(jì)算在線用戶的數(shù)量,例如:15,就表示如果用戶在15分鐘后不活動(dòng)(發(fā)出http請(qǐng)求)cs系統(tǒng)將視該用戶不在線。

name:名稱

type:類的名字空間與所在的程序集合

connectionstringname:數(shù)據(jù)庫(kù)連接字符串節(jié)點(diǎn)的key。通過(guò)這個(gè)key就可以找到連接數(shù)據(jù)庫(kù)的用戶名與密碼

enablepasswordretrieval:是否打開取回秘密功能

enablepasswordreset:是否打開秘密重新設(shè)功能

requiresquestionandanswer:注冊(cè)時(shí)是否需要填寫question與answer

requiresuniqueemail:注冊(cè)時(shí)是否email唯一

passwordformat:密碼的加密格式

applicationname:使用該membership應(yīng)用程序的名稱

description:描述信息

以下4個(gè)參數(shù)是ccs中添加的,目的是給注冊(cè)用戶自動(dòng)開通相冊(cè)和博客

autocreateblog:是否當(dāng)用戶注冊(cè)時(shí)自動(dòng)為該用戶建立一個(gè)blog

defaultbloggroupid:默認(rèn)的建立blog的分組id

autocreategallery:是否當(dāng)用戶注冊(cè)時(shí)自動(dòng)為該用戶建立一個(gè)相冊(cè)

defaultgallerygroupid:默認(rèn)的建立相冊(cè)的分組id

用reflector.exe打開memberrole.dll,你可以看到以下的內(nèi)容:

再打開microsoft.scalablehosting.configuration節(jié)點(diǎn)

這次我們只關(guān)注兩個(gè)類membershipconfig、membershipconfighandler。membershipconfighandler實(shí)現(xiàn)了iconfigurationsectionhandler接口。也就是說(shuō),cs啟動(dòng)后如果調(diào)用configurationsettings.getconfig("memberrolesprototype/membership"),系統(tǒng)將會(huì)自動(dòng)的調(diào)用membershipconfighandler中的create方法把web.config中memberrolesprototype/membership的配置內(nèi)容讀入進(jìn)行處理。先看以下create做了些什么:

public virtual object create(object parent, object configcontextobj, xmlnode section)
{
      membershipconfig config1 = new membershipconfig(parent as membershipconfig);
      int num1 = -1;
      configutils.getandremovepositiveintegerattribute(section, "userisonlinetimewindow", ref num1);
      if (num1 > 0)
      {
            config1.userisonlinetimewindow = num1;
      }
      string text1 = null;
      configutils.getandremovestringattribute(section, "hashalgorithm", ref text1);
      if ((text1 != null) && (text1.length > 0))
      {
            config1.hashalgorithmtype = text1;
      }
      configutils.checkforunrecognizedattributes(section);
      membershipprovider provider1 = null;
      foreach (xmlnode node1 in section.childnodes)
      {
            if (node1.nodetype != xmlnodetype.element)
            {
                  continue;
            }
            if (node1.name != "providers")
            {
                  throw new configurationexception("unrecognized tag: " + node1.name, node1);
            }
            foreach (xmlnode node2 in node1.childnodes)
            {
                  if (node2.nodetype == xmlnodetype.element)
                  {
                        if (node2.name != "add")
                        {
                              throw new configurationexception("unrecognized tag: " + node2.name, node2);
                        }
                        if (provider1 != null)
                        {
                              throw new configurationexception("only one provider can be configured", node2);
                        }
                        string text2 = null;
                        string text3 = null;
                        configutils.getandremoverequirednonemptystringattribute(node2, "name", ref text2);
                        configutils.getandremoverequirednonemptystringattribute(node2, "type", ref text3);
                        namevaluecollection collection1 = new namevaluecollection();
                        foreach (xmlattribute attribute1 in node2.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;
                  }
            }
      }
      return config1;
}

代碼有點(diǎn)長(zhǎng),其實(shí)這里就是把web.config下面membership節(jié)點(diǎn)的配置信息讀入,進(jìn)行初始化,然后通過(guò)gettype與activator.createinstance方法反射后實(shí)例化一個(gè)membershipprovider。

membershipprovider又是什么,繼續(xù)看看:

public abstract class membershipprovider : providerbase
{
      // events
      public event membershipvalidatepasswordeventhandler validatingpassword;
 
      // methods
      protected membershipprovider();
      public abstract bool changepassword(string username, string oldpassword, string newpassword);
      public abstract bool changepasswordquestionandanswer(string username, string password, string newpasswordquestion, string newpasswordanswer);
      public abstract membershipuser createuser(string username, string password, string email, string passwordquestion, string passwordanswer, bool isapproved, object provideruserkey, out membershipcreatestatus status);
      protected virtual byte[] decryptpassword(byte[] encodedpassword);
      public abstract bool deleteuser(string username, bool deleteallrelateddata);
      internal string encodepassword(string pass, int passwordformat, string salt);
      protected virtual byte[] encryptpassword(byte[] password);
      public abstract membershipusercollection findusersbyemail(string emailtomatch, int pageindex, int pagesize, out int totalrecords);
      public abstract membershipusercollection findusersbyname(string usernametomatch, int pageindex, int pagesize, out int totalrecords);
      internal string generatesalt();
      public abstract membershipusercollection getallusers(int pageindex, int pagesize, out int totalrecords);
      public abstract int getnumberofusersonline();
      public abstract string getpassword(string username, string answer);
      public abstract membershipuser getuser(object provideruserkey, bool userisonline);
      public abstract membershipuser getuser(string username, bool userisonline);
      public abstract string getusernamebyemail(string email);
      protected virtual void onvalidatingpassword(validatepasswordeventargs e);
      public abstract string resetpassword(string username, string answer);
      internal string unencodepassword(string pass, int passwordformat);
      public abstract bool unlockuser(string username);
      public abstract void updateuser(membershipuser user);
      public abstract bool validateuser(string username, string password);
 
      // properties
      public abstract string applicationname { get; set; }
      public abstract bool enablepasswordreset { get; }
      public abstract bool enablepasswordretrieval { get; }
      public abstract int maxinvalidpasswordattempts { get; }
      public abstract int minrequirednonalphanumericcharacters { get; }
      public abstract int minrequiredpasswordlength { get; }
      public abstract int passwordattemptwindow { get; }
      public abstract membershippasswordformat passwordformat { get; }
      public abstract string passwordstrengthregularexpression { get; }
      public abstract bool requiresquestionandanswer { get; }
      public abstract bool requiresuniqueemail { get; }
 
      // fields
      private membershipvalidatepasswordeventhandler _eventhandler;
      private const int salt_size_in_bytes = 0x10;
}

原來(lái)membershipprovider是實(shí)現(xiàn)繼承了providerbase的一個(gè)類,其實(shí)providerbase并沒(méi)有什么,看看代碼

public abstract class providerbase
{
      // methods
      protected providerbase();
      public virtual void initialize(string name, namevaluecollection config);
 
      // properties
      public virtual string description { get; }
      public virtual string name { get; }
 
      // fields
      private string _description;
      private bool _initialized;
      private string _name;
}

providerbase僅僅只是保護(hù)了兩個(gè)虛屬性的類,設(shè)置這個(gè)類只是一種設(shè)計(jì)模式,沒(méi)有特別的用途。我們把重點(diǎn)集中到membershipprovider上,membershipprovider類是provider構(gòu)架的一種體現(xiàn)形式,provider構(gòu)架常常用到對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)上,實(shí)現(xiàn)多數(shù)據(jù)庫(kù),同時(shí)也可以很好的隔離數(shù)據(jù)層與業(yè)務(wù)層的代碼有利于協(xié)作開發(fā)。具體實(shí)現(xiàn)是這樣的,先把要操作數(shù)據(jù)庫(kù)的方法抽象出來(lái),單獨(dú)的放入一個(gè)abstract類,例如:membershipprovider,然后通過(guò)繼承,把這些抽象的方法全部的實(shí)現(xiàn)出來(lái),例如:sqlmembershipprovider。這樣有什么好處呢?對(duì)于三層構(gòu)架的web應(yīng)用程序來(lái)說(shuō),中間的業(yè)務(wù)邏輯層調(diào)用操作數(shù)據(jù)庫(kù)的方法是從membershipprovider,對(duì)于該層來(lái)說(shuō)它并不關(guān)心該抽象層是如何被繼承后實(shí)現(xiàn)抽象方法的。它只關(guān)心抽象層中是否有它想要的方法。如果能理解到這里,嘿嘿,我們的機(jī)會(huì)就來(lái)了,因?yàn)檫@隔離了具體的數(shù)據(jù)庫(kù)操作實(shí)現(xiàn),更進(jìn)一步說(shuō)就是隔離了使用何種數(shù)據(jù)庫(kù)。再?gòu)膱F(tuán)隊(duì)協(xié)作考慮,假設(shè)你的membershipprovider定義的完善后,繼承membershipprovider實(shí)現(xiàn)sql server操作的sqlmembershipprovider類中的方法無(wú)論怎么改變,都不會(huì)影響其它人員在業(yè)務(wù)邏輯層的開發(fā)。聽起來(lái)這種方式好像很美,但是要實(shí)現(xiàn)這樣的功能還需要一個(gè)關(guān)鍵的技術(shù),那就是反射,所以我們看到在配置的字段里有這樣的字節(jié):。

type="openlab.autoregister.csautobloggallerymembershipprovider, openlab.csaddons"

這就是為了通過(guò)反射找到membershipprovider具體方法實(shí)現(xiàn)的類而做的準(zhǔn)備。

注:由于分析的代碼來(lái)源于寶玉的ccs,在ccs中為了實(shí)現(xiàn)注冊(cè)后能自動(dòng)開通博客與相冊(cè)又繼承了sqlmembershipprovider類,重寫了幾個(gè)方法(關(guān)鍵是其中的initialize與createuser方法)。

只要你繼承membershipprovider類,對(duì)其中的抽象方法進(jìn)行實(shí)現(xiàn),無(wú)論你是實(shí)現(xiàn)對(duì)access的操作,還是其它數(shù)據(jù)庫(kù),都是沒(méi)有問(wèn)題的。在asp.net 2.0 beta2中的membership已經(jīng)提供access與sql server兩種數(shù)據(jù)庫(kù)操作實(shí)現(xiàn)。不過(guò)memberrole.dll程序集中只實(shí)現(xiàn)了sqlmembershipprovider,也就是對(duì)sql server的操作。

membership是一個(gè)沒(méi)有表示層的運(yùn)用組件,它包含了邏輯層與數(shù)據(jù)操作層,數(shù)據(jù)層我在這個(gè)專題中就不多做解釋,他的實(shí)現(xiàn)是在sqlmembershipprovider類中,你可以通過(guò)reflector.exe慢慢研究。上面的文字說(shuō)過(guò),實(shí)現(xiàn)provider模式后業(yè)務(wù)邏輯層對(duì)數(shù)據(jù)層具體實(shí)現(xiàn)就不關(guān)心了,在memberrole.dll中的membership,它把所有的這些邏輯用一個(gè)類包裝起來(lái),那就是membership類:

對(duì)于引用memberrole.dll實(shí)現(xiàn)membership功能的web app(dnn,cs就是典型)來(lái)說(shuō),只要做合適的配置之后就可以直接使用了。

例如,要建立一個(gè)用戶只要調(diào)用membership.createuser的靜態(tài)方法,就可以完成(membership會(huì)根據(jù)內(nèi)部的方法和具體的數(shù)據(jù)庫(kù)操作,把用戶信息寫入數(shù)據(jù)庫(kù))。

對(duì)于使用membership來(lái)開發(fā)web app的程序員來(lái)說(shuō),完全可以不必要了解這些細(xì)節(jié),asp 2.0 beta2就沒(méi)有提供這樣的機(jī)會(huì),ms只要求你會(huì)用就可以了,不過(guò)很慶幸的是cs給我們提供了這樣的一個(gè)機(jī)會(huì),了解這些操作的實(shí)質(zhì)(包括url rewrite等功能也是一樣,這些功能都可以在asp 2.0 beta2中直接使用,而不要構(gòu)架如何代碼)。

這個(gè)專題只是大致的講解了membership,下一個(gè)專題,我們將更深入的去看看membership的數(shù)據(jù)層的操作實(shí)現(xiàn)以及數(shù)據(jù)庫(kù)表的設(shè)計(jì)(包括存儲(chǔ)過(guò)程)。


發(fā)表評(píng)論 共有條評(píng)論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 馆陶县| 疏勒县| 民乐县| 淮北市| 新乡市| 忻城县| 灌阳县| 盐亭县| 庆城县| 新蔡县| 永平县| 积石山| 肃宁县| 北宁市| 东阿县| 永川市| 温泉县| 米林县| 洛浦县| 阆中市| 上饶市| 宜阳县| 百色市| 察哈| 米泉市| 济源市| 普洱| 沈阳市| 台江县| 建始县| 喀什市| 和硕县| 定西市| 保山市| 镇宁| 富蕴县| 剑川县| 阜阳市| 高雄县| 峡江县| 仁怀市|