【问题标题】:Trying to create 'SuperUser Class' with ASPNET ProfileBase and MembershipUser尝试使用 ASPNET ProfileBase 和 MembershipUser 创建“超级用户类”
【发布时间】:2010-02-18 21:12:27
【问题描述】:

我最近安装了aspnetdb,一直在自定义 出于我的应用程序设计的目的。我已经扩展了 ASPNET 提供者作为我的课程设计的一部分:MyMembershipProvider、MyProfileProvider、 和 MyRoleProvider。那里一切正常。

现在,根据我的系统要求,我需要添加自定义数据,但我不需要 想使用 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中基本上遵循了John Galloway的建议

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

}

好的,到目前为止一切顺利。我有一个 CustomUser 类,可用于获取和设置 个人资料数据如下:

CustomUser _cu = CustomUser.GetUserProfile(用户名);

这将返回我的所有自定义字段以及继承自的属性 配置文件库。伟大的。

但是,如果我想向用户的个人资料添加其他属性怎么办?即,提供的那些 通过 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 = 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

     }

}

【问题讨论】:

    标签: c# asp.net-membership profile


    【解决方案1】:

    代码,您似乎打算做很多不必要的工作。 并且没有令人信服的理由将成员资格和配置文件基础结构聚合在包装类中,并且有很多理由不这样做。

    第一个原因是你不能在任何地方使用它。您将不得不建立自己的基础设施。我已经做到了,它并不好玩。

    有趣的是编写已建立的 api 并利用数百万美元和数千工时投入到设计、开发和测试基于提供程序的 ASP.NET 系统中。

    如果您希望拥有一个自定义会员用户,第一步是从 MembershipUser 继承,以便您可以轻松实现一个直接插入 asp.net 框架的自定义提供程序。

    请参阅 here 了解快速且易于理解的示例,参阅 here 了解标准文档。

    就在您的用户中撰写个人资料而言。 Membership、Roles 和 Profile 是基础架构的独立但相关的方面,并且已在逻辑上分离以最大限度地提高灵活性和重用性。

    我相信你会发现学习编写基于提供程序的 api 的代码并专注于解决有趣的问题比重新发明轮子更有价值。

    祝你好运

    【讨论】:

    • 非常感谢 Sky,这很有帮助。我已经认真编辑了我的问题,以提供我的想法的完整背景。根据您的回答,我想我的问题是 - 即使我从 MembershipUser 继承,我如何解释我想通过 ProfileBase 公开的属性?我不是想重新发明轮子,但我希望能够通过组合它们来提供用户的完整快照。
    • @Code Sherpa,您不需要结合会员资格和个人资料,它们都可以通过 httpcontext.current 随时随地访问。个人资料系统的流动性并不适合加入您的会员资格。如果您有一些需要关注会员用户的数据点,只需将它们添加到会员用户/数据库。不要从个人资料中提取以填充成员资格。我什至没有时间解释这个想法有多糟糕。哈哈。相信我。我已经从根本上处理了提供者模型。
    • 再次感谢天空。我将继续按照您提供的示例进行操作。作为一个临别问题,您介意看一下我编辑的帖子中引用的 John Galloway 的博客帖子吗?我一直在关注他的示例,该示例通过从 ProfileBase 继承来创建自定义用户配置文件。如上所述,您建议从 MembershipUser 继承而不是将配置文件属性烘焙到我的自定义用户类中。那么,约翰的建议完全是错误的吗?我应该如何访问 ProfileBase?再次感谢。
    • @Code Sherpa,正如我所说,个人资料和会员资格是不同的。它们是不相同的。我不相信约翰在文章中的任何地方都提到了会员资格,除了获取当前用户的用户名以初始化配置文件库,所以我不确定您从哪里得到合并会员资格和个人资料是个好主意的想法。我不认为它来自那个帖子。这篇文章很好,并为否则可能会有点混乱的过程提供了很好的指导,r.e.网络应用与网站中的配置文件。
    • 好的,谢谢天空。我是 ASPNET DB 的新手,并且正在学习我的方法。我一定在某些时候混淆了会员资格和个人资料。感谢您直截了当。我将按照您提供的示例进行操作。再次感谢您的帮助。
    【解决方案2】:

    您还必须实现自己的 Custom Membership Provider 来填充它。

    【讨论】:

    • 啊,我想我刚刚意识到我的问题(你指出了但花了一段时间...... :))。我的 CustomUser 类扩展了 ProfileBase,我需要编写一个扩展 MembershipUser 的 CustomMembershipUser 类。然后,我猜我应该能够像我在帖子末尾所做的那样在我的 User 类中将两者结合起来?
    • 我认为上面的 Sky Sanders 提供了比我更好的解释。看看他提供的链接。创建自定义 MembershipProvider 非常容易,只是有点乏味,因为您需要覆盖很多方法/属性。这样,要获取您的 User 对象,您可以执行以下操作: CustomUser user = (CustomUser)Membership.GetUser();
    • @bryce - 实际上只有几个方法,我相信 2,您需要启动并运行一个骨架成员资格提供程序,ValidateUser() 和 GetUser(userName,isUserOnline)。您实现的其余部分以支持您希望利用的框架功能。这真的再简单不过了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-02
    • 2021-10-13
    • 2023-03-15
    • 2015-08-21
    • 1970-01-01
    • 2017-08-19
    相关资源
    最近更新 更多