內建的提供者能讓您用來建立實作提供者合約的自訂類別,這麼做的常見原因是要控制提供者資料的儲存。舉例來說,Membership提供者是ASP.NET成員資格服務預設的介面,而這項服務將資料放在資料存放區的ASP.NET專屬資料表。不過現有的許多程式本身已經具備成員資格資料表的概念,如果想用本身的資料表來替換ASP.NET專屬的資料表,並且能夠使用能與成員資格提供者共同運作的內建控制項,就得大費周章,但卻只能得到運作時的小小回報。但無論如何,藉著建立實作了MembershipProvider類別重要方法的類別,您能以自訂類別透過現有的資料存放區來執行成員資格的運作。這種類型的自訂方式不只在運作時不會受限於資料庫,您也能從自訂類別叫用協力廠商的API。
在接下來的例子中,我們就要繼承MembershipProvider自訂資料成員提供者:
namespace MVPHacks.Security
{
///
/// Summary description for MVPHacksCustomMembershipProvider
///
public class MVPHacksCustomMembershipProvider :
System.Web.Security.MembershipProvider
{
public MVPHacksCustomMembershipProvider()
{
}
}
}
|
Visual Studio
2005可以很容易的讓您建立抽象類別或介面的基本架構實作,如下圖,只要在類別或命名空間按下第1個字母底下的短線,就會列出繼承的下拉式清單,再從中選取,Visual
Studio 2005就會建立基本架構實作。
只要替成員資格提供者建立基本架構實作,就會實作出類別裡abstract(C#)或MustInherit(VB.NET)的每個屬性或方法的stub,並且包含一行會拋出例外的程式(註明此方法尚未實作)。這是一項助益甚大的功能,因為它節省了您尋找文件、嘗試瞭解類別必須實作或定義哪些方法的時間。此外,就算沒有實作提供者的所有方法也沒關係,因為這只會拋出NotSupportedException例外,讓叫用者知道目前的提供者不支援所叫用的屬性或方法。
以下是您選取實作選項之後,Visual Studio 2005所產生的部分結果:
public class MVPHacksCustomMembershipProvider :
System.Web.Security.MembershipProvider
{
public override string ApplicationName
{
get{throw new Exception("The method or operation is not
implemented.");}
set{throw new Exception("The method or operation is not
implemented.");}
}
public override bool ChangePassword(string username, string oldPassword,
string newPassword)
{
throw new Exception("The method or operation is not implemented.");
}
}
|
您可以在自己的範例作此測試,就能看到所有的方法和屬性;再次強調,以上只是部分結果。您或許會想要將沒有實作的方法所拋出的一般例外,更改成NotSupportedException,這能讓使用這項實作的人透過一致且清楚的方式,在執行階段偵測您是否實作了特定的方法。
更改前:
public override bool ChangePassword(string username, string oldPassword,
string newPassword)
{
throw new Exception("The method or operation is not implemented.");
}
|
更改後:
public override bool ChangePassword(string username, string oldPassword,
string newPassword)
{
throw new NotSupportedException();
}
|
要完成這項工作,最簡單的方式是將Exception("The method or operation is not
implemented.");字串換成NotSupported();,這樣的改變能讓未實作的方法更符合提供者利用一致的例外提醒使用者未支援方法的概念。
接著讓我們看另一個非常簡單的類別,這個類別會模仿您現有的驗證管理員。請記住,這裡的目的只是概念的示範,並非要提供功能完整的提供者。事實上,這個例子示範了一種很棒的方式,能將登入的行為加到已具有安全功能但要使用內建登入控制項的ASP.NET程式。在此例,只要少少的幾行程式碼以及一些設定,我們就能讓網站具備登入功能:
Namespace MVPHacks.CustomAuthentication
{
public class ExistingAuthManager
{
public bool ValidateUser(string username, string password)
{
if (string.Compare(username, "mvphacks", true) != 0)
return false;
if (string.Compare(password, "mvphacks", true) != 0)
return false;
return true;
}
}
}
|
下個步驟要在叫用ValidateUser方法時,能讓我們自訂的MembershipProvider類別叫用剛才加入的登入功能,作法如下:
public override bool ValidateUser(string username, string password)
{
ExistingAuthManager authMgr = new ExistingAuthManager();
return authMgr.ValidateUser(username, password);
}
|
您可能已經注意到,我們的ExistingAuthManager的命名空間與自訂類別MembershipProvider的命名空間並不相同,因此我們需要加上using(C#)陳述式或imports(VB.NET)陳述式。Visual
Studio 2005有個簡單的方式可以完成這件事,如下圖,按下類別名稱最後一個字元的底線,將會自動為您加入using陳述式。
現在我們已經在類別裡實作了叫用ExistingAuthManager的方法,這會在程式裡模仿現有的安全管理員,接著就要在web.config檔案進行提供者的組態,如下所示:
<membership defaultProvider="MVPHacksMembershipProvider">
<providers>
<add connectionStringName="LocalSqlServer"
name="MVPHacksMembershipProvider"
type="MVPHacks.Security.MVPHacksCustomMembershipProvider,
MVPHacksCommon"/>
</providers>
</membership>
|
我們還要修改web.config檔案裡的authentication和authorization區段:
<authentication mode="Forms">
<forms loginUrl="/user/login.aspx"></forms>
</authentication>
<authorization>
<deny users="?"/>
</authorization>
|
雖然前述的例子要求所有未經驗證的使用者轉到loginUrl指定的頁面,不過對本例來說loginUrl並非必要的特性,但是大家經常誤認為使用表單驗證就必須將登入頁面放在網站根目錄,所以這裡特別示範不放在根目錄的作法。
建立登入頁面只是一件簡單的滑鼠拖放工作:login.aspx表單加入使用者資料夾之後,就只要從工具箱將Login控制項拖到我們的頁面即可(如下圖)。雖然Login控制項有許多屬性可以設定,但至少您必須將DestinationPage屬性值設定成default.aspx或其他登入完成之後的目的頁面。
現在最棒的是不需要額外的工作就能使用LoginStatus、LoginName、LoginView控制項。您也能實作方法來建立使用者,並且執行其他的成員資格功能,然後繼續使用其他內建的控制項。
如果想深入瞭解更多內建成員資格、角色管理、設定檔、Web組件個人化的提供者實例,微軟ASP.NET Developer
Center網站有豐富的資料。您也可以下載Sample Access Provider Start
Kit,這是個讓每個提供者都能以微軟Access當作儲存媒介的C#類別庫。或許您不需要讓提供者將資料存放在Access,但是這個Start
Kit以現有的內建模型為基礎,提供了更完整的提供者實作範例,以及詳盡討論每一種內建提供者的白皮書,是深入研究提供者很好的資源。
|