2010-02-18 50 views
0

我最近安裝了aspnetdb,並且已經爲我的應用程序設計定製了 。我將ASPNET 提供程序擴展爲我的類設計的一部分:MyMembershipProvider,MyProfileProvider, 和MyRoleProvider。一切都很好。試圖用ASPNET ProfileBase和MembershipUser創建'超級用戶類'

現在,根據我係統的需求,我需要添加自定義數據,並且我不想使用在aspnet_Profile中提供的名稱/值設計。所以,我有 創建了兩個自定義表:

dbo.Profile

CREATE TABLE [dbo].[Profiles](
    [profileid] [int] IDENTITY(1,1) NOT NULL, 
    [userid] [uniqueidentifier] NOT NULL, 
    [username] [varchar](255) COLLATE Latin1_General_CI_AI NOT NULL, 
    [applicationname] [varchar](255) COLLATE Latin1_General_CI_AI NOT NULL, 
    [confirmcode] [varchar](255) COLLATE Latin1_General_CI_AI NOT NULL, 
    [isanonymous] [bit] NULL, 
    [lastactivity] [datetime] NULL, 
    [lastupdated] [datetime] NULL, 
CONSTRAINT [PK__Profiles__1DB06A4F] PRIMARY KEY CLUSTERED 
(
    [profileid] ASC 
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY], 
CONSTRAINT [PKProfiles] UNIQUE NONCLUSTERED 
(
    [username] ASC, 
    [applicationname] ASC 
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] 
) ON [PRIMARY] 

dbo.ProfileData

CREATE TABLE [dbo].[ProfileData](
    [profiledataid] [int] IDENTITY(1,1) NOT NULL, 
    [profileid] [int] NOT NULL, 
    [lastname] [varchar](50) COLLATE Latin1_General_CI_AI NULL, 
    [firstname] [varchar](50) COLLATE Latin1_General_CI_AI NULL, 
    [alternateemail] [varchar](50) COLLATE Latin1_General_CI_AI NULL, 
    [zipcode] [varchar](50) COLLATE Latin1_General_CI_AI NULL, 
    [birthmonth] [tinyint] NULL, 
    [birthday] [tinyint] NULL, 
    [birthyear] [int] NULL, 
    [gender] [varchar](10) COLLATE Latin1_General_CI_AI NULL, 
    [city] [varchar](50) COLLATE Latin1_General_CI_AI NULL, 
    [state] [varchar](50) COLLATE Latin1_General_CI_AI NULL, 
    [country] [varchar](50) COLLATE Latin1_General_CI_AI NULL, 
    [ipaddress] [varchar](50) COLLATE Latin1_General_CI_AI NULL, 
    [sessionid] [bigint] NULL, 
CONSTRAINT [PK_ProfileData] PRIMARY KEY CLUSTERED 
(
    [profiledataid] ASC 
)WITH (IGNORE_DUP_KEY = OFF) ON [PRIMARY] 
) ON [PRIMARY] 

現在,因爲我有自定義數據擴展了ASPNET基礎設施,我有 編寫了一個自定義用戶類,幫助將該數據擴展爲配置文件 快照的一部分。我基本上遵循約翰·加洛韋的建議,this blog

public class CustomUser : ProfileBase 
{ 

     public customuser() {} 

     public static CustomUser GetCustomUserProfile(string username) 
     { 
      return System.Web.Profile.ProfileBase.Create(username) as CustomUser; 
     } 

     #region ProfileBase Extended Properties 

     [SettingsAllowAnonymous(false), CustomProviderData("FirstName;string")] 
     public string FirstName { get { return base["FirstName"] as string; } set { base["FirstName"] = value; } } 

     [SettingsAllowAnonymous(false), CustomProviderData("LastName;string")] 
     public string LastName { get { return base["LastName"] as string; } set { base["LastName"] = value; } } 

     [SettingsAllowAnonymous(false), CustomProviderData("AlternateEmail;string")] 
     public string AlternateEmail { get { return base["AlternateEmail"] as string; } set { base["AlternateEmail"] = value; } } 

     // AND SO ON... 

     #endregion 

} 

OK,到目前爲止,一切順利。我有一個CustomUser類,我可以用於獲取和設置 配置文件數據,例如:

CustomUser _cu = CustomUser.GetUserProfile(username);

除了從 ProfileBase繼承的屬性之外,這將返回我所有的自定義字段。大。

但是如果我想將其他屬性添加到用戶的配置文件?也就是說,那些提供 通過ASPNET的類的MembershipUser如IsOnline,PasswordQuestion,IsLockedOut等.. 從獲得的MembershipUser基本屬性,我可以嘗試像:

public class CustomUser : MembershipUser 
    { 
     public CustomUser(string providerName, string name, object providerUserKey, string email, 
           string passwordQuestion, string comment, bool isApproved, bool isLockedOut, 
           DateTime creationDate, DateTime lastLoginDate, DateTime lastActivityDate, 
           DateTime lastPasswordChangedDate, DateTime lastLockoutDate) 
      : base(
       providerName, name, providerUserKey, email, passwordQuestion, comment, isApproved, isLockedOut, 
       creationDate, lastLoginDate, lastActivityDate, lastPasswordChangedDate, lastLockoutDate) 
     { 
     } 

     protected CustomUser() 
     { 
     } 

     // e.g. no desire to use Profile, can just add data 
     // say, from a flat record containing all user data 
     public string MyCustomField { get; set; } 
    } 

但是,因爲我也一直繼承從ProfileBase和C#不允許 允許多重繼承(即,我不能做CustomUser:ProfileBase,MembershipUser), 我卡住了一些問題。建立我的用戶級別 的最佳方式是什麼User _user = new User();返回與已驗證用戶相關的屬性的完整範圍?

下面是我在這個「超級用戶」一流的首次嘗試,但我有一個真正的困難時期 搞清楚如何創建類對象的新實例,使得兩個CustomUser 和被的MembershipUser創建。

我對此有何看法?

public class User 
    { 

     public User() { } 

     public static User GetUserProfile(string username) 
     { 
      // return combined profile based on username 
     } 

     #region CustomUser Members 

     private CustomUser _customUser 
     { 
      get 
      {  
       if (UserName != null) 
       { 
        try 
        { 
         return ProfileBase.Create(UserName) as CustomUser; 
        } 
        catch { return null; } 
       } 
       else 
       { 
        try 
        { 
         // this will work if the site user is log'd in 
         return ProfileBase.Create(Membership.GetUser().UserName) as CustomUser; 
        } 
        catch { return null; } 
       } 

      } 
     } 

     public string FirstName 
     { 
      get 
      { 
       if (_customUser != null) 
       { 
        return _customUser.FirstName; 
       } 
       return string.Empty; 
      } 

      set 
      { 
       if (_customUser != null) 
       { 
        _customUser.FirstName = value; 
       } 
      } 
     } 

     public string LastName 
     { 
      get 
      { 
       if (_customUser != null) 
       { 
        return _customUser.LastName; 
       } 
       return string.Empty; 
      } 

      set 
      { 
       if (_customUser != null) 
       { 
        _customUser.LastName = value; 
       } 
      } 
     } 


     #endregion 

     #region MembershipUser Members 

     //corresponding MembershipUser 
     private MembershipUser _membershipUser 
     { 
      get 
      { 
       if (UserName != null) 
       { 
        return Membership.GetUser(UserName); 
       } 
       return null; 
      } 
     } 

     //Properties looked up from MembershipUser 

     public string UserName 
     { 
      get 
      { 
       if (_membershipUser != null) 
       { 
        return _membershipUser.UserName; 
       } 
       return string.Empty; 
      } 

     } 

     public string Email 
     { 
      get 
      { 
       if (_membershipUser != null) 
       { 
        return _membershipUser.Email; 
       } 
       return string.Empty; 
      } 

     } 

     public object ProviderUserKey 
     { 
      get 
      { 
       if (_membershipUser != null) 
       { 
        return _membershipUser.ProviderUserKey; 
       } 
       return null; 
      } 
     } 


     #endregion 

    } 

} 

回答

1

代碼,看起來你打算做很多不必要的工作。 並沒有令人信服的理由來聚合包裝類中的成員資格和配置文件基礎設施,以及許多原因。

第一個原因是你不能在任何地方使用它。你將不得不建立你自己的基礎設施。我已經做到了,而且沒有什麼樂趣。

什麼是有趣的是編碼到一個既定的API和採取的數以百萬計的投入設計美元和數千個工時的優勢,開發和測試ASP.NET的供應商的系統。

如果你想有一個自定義成員資格用戶的第一步是從繼承的MembershipUser,讓您可以輕鬆實施正確插入到asp.net框架自定義提供。

here爲標準文檔一個非常快速和容易消化的例子,here

就你用戶中的構成配置文件而言。成員資格,角色和配置文件是基礎架構的獨立但相關的方面,並在邏輯上分離以最大限度地提高靈活性和重用性。

我敢肯定,你會發現在學習代碼提供商基於API和重點解決不是重新發明輪子有趣的問題更多的價值。

祝你好運

+0

謝謝天空,這很有幫助。我認真編輯了我的問題,提供了我的思想背景。根據你的回答,我想我的問題是 - 即使我從MembershipUser繼承,我如何解釋我想通過ProfileBase公開的屬性?我不想重新發明輪子,但我希望能夠通過組合它們來提供用戶的完整快照。 – 2010-02-19 18:33:17

+0

@Code Sherpa,你不需要結合成員資格和個人資料,他們都可以隨時隨地通過httpcontext.current獲得。配置文件系統的流暢性並不能成爲您成爲會員的好選擇。如果您有一些需要遵循成員身份用戶的數據點,只需將其添加到membershipuser /數據庫即可。不要從個人資料中提取會員資格。我甚至沒有時間來解釋這個想法有多糟糕。大聲笑。相信我。我已經從金屬上處理了提供者模型。 – 2010-02-19 18:47:38

+0

再次感謝天空。我會繼續並按照您提供的示例進行操作。作爲一個離別的問題,你介意看看我編輯過的文章中引用的John Galloway的博客帖子嗎?我一直在關注他的例子,它通過從ProfileBase繼承來創建一個自定義用戶配置文件。如上所述,您建議從MembershipUser繼承並且不將配置文件屬性烘焙到我的自定義用戶類中。那麼,約翰的建議是錯誤的?我應該如何訪問ProfileBase?再次感謝。 – 2010-02-21 17:37:11

1

你必須實現你自己的Custom Membership Provider來填充它。

+0

啊,我想我剛剛意識到我的問題(你指出,但它需要一段時間:))。我的CustomUser類擴展了ProfileBase,我需要編寫一個擴展MembershipUser的CustomMembershipUser類。然後,我猜我應該能夠在我的用戶類中以我在文章末尾完成的相同方式將這兩者結合起來? – 2010-02-19 18:38:09

+0

我認爲上面的Sky Sanders提供了比我更好的解釋。看看他提供的鏈接。創建自定義MembershipProvider非常容易,它只是一種乏味,因爲有很多方法/屬性需要重寫。 這樣,讓你的用戶對象,你會做這樣的事情: CustomUser用戶=(CustomUser)Membership.GetUser(); – 2010-02-19 19:15:58

+0

@bryce - 實際上只有幾個方法,2我相信,你需要獲得骨架成員資格提供程序並運行,ValidateUser()和GetUser(userName,isUserOnline)。您實施的其餘部分支持您希望利用的框架功能。它真的不會容易。 – 2010-02-20 03:00:08