經過前兩章的建置,我們已經擁有一套功能完善、甚至具備專業級特性的登入系統。然而,若要長期仰賴微軟內建的 ASP.NET 網站管理工具來維護使用者帳號,顯然不夠靈活,也無法滿足實際專案中依權限動態調整後台介面的需求。雖然資深開發人員可直接操作資料庫結構,但對大多數開發者而言,透過標準的 Membership、Profile 與 Roles 物件進行資料繫結,才是更務實的選擇。
在 .NET 1.x 時代,將複雜物件繫結至 GridView 等資料控制項往往令人頭痛。自 .NET 2.0 引入 ObjectDataSource (ODS) 後,我們可以將每位使用者視為一筆資料列,把 Membership.GetAllUsers() 視為一條 SELECT 查詢。然而,標準的 MembershipUser 類別缺乏資料繫結所需的主鍵、唯讀等中繼資料屬性,因此必須透過包裝類別 (Wrapper) 為其補充這些特性。
繼承 MembershipUser 並標記 UserName 為 [DataObjectField(true)],使 GridView 能正確識別主鍵並產生編輯模板。以下為關鍵程式碼片段(完整版本請參考原始碼附件):
Public Class MembershipUserWrapper
Inherits MembershipUser
<DataObjectField(True)> _
Public Overrides ReadOnly Property UserName() As String
Get
Return MyBase.UserName
End Get
End Property
' 建構子略...
End Class
集中資料存取邏輯,提供 Select、Insert、Update、Delete 四大方法,並以 <DataObjectMethod> 屬性標註對應操作類型:
GetMembers() 支援依使用者名稱查詢、篩選已核准/未核准使用者。Insert() 呼叫 Membership.CreateUser 並處理密碼與密碼提示答案。Update() 僅在欄位實際變更時呼叫 Membership.UpdateUser,減少不必要的資料庫往返。Delete() 直接呼叫 Membership.DeleteUser。在 Default.aspx 放置 GridView 與 ObjectDataSource,經由「設定資料來源」精靈選取 MembershipUserODS 類別與對應方法,並將 OldValuesParameterFormatString 設為 {0},即可完成雙向繫結。同樣模式可套用至 Roles 與 Profile 管理,文中並提供 RoleDataODS 與 ProfileODS 完整程式碼,其中 Profile 部分修正了 ProfileCommon 首次存取前屬性集合無法正確列舉的已知 Bug。

透過這層薄薄的包裝與 ODS 橋接,原本複雜的 Membership 物件模型即可無縫整合至資料繫結架構,快速建構出可維護的後台管理介面。