如何使用SimpleMembership管理配置文件?

19

我有一个基于互联网模板的ASP.NET MVC 4站点。我使用了SimpleMembership,这是我在该模板上设置的。

我可以修改为我创建的Users表,但我不确定修改我添加的额外字段的“正确”方式。我想要Fullname、Email等信息,并将它们添加到用户表中,但似乎没有通过SimpleMembership WebSecurity.*静态方法进行更新的方法。

你应该只是在SimpleMembership API之外使用EF自己更新这些属性吗?

4个回答

22

1 - 您需要启用迁移,最好使用EntityFramework 5。

2 - 将您的

WebSecurity.InitializeDatabaseConnection("DefaultConnection", "UserProfile", "UserId", "EmailAddress", autoCreateTables: true); 

在YourMvcApp/Migrations/Configuration.cs类中的Seed方法中添加以下内容

    protected override void Seed(UsersContext context)
    {
        WebSecurity.InitializeDatabaseConnection(
            "DefaultConnection",
            "UserProfile",
            "UserId",
            "UserName", autoCreateTables: true);

        if (!Roles.RoleExists("Administrator"))
            Roles.CreateRole("Administrator");

        if (!WebSecurity.UserExists("lelong37"))
            WebSecurity.CreateUserAndAccount(
                "lelong37",
                "password",
                new {Mobile = "+19725000000", IsSmsVerified = false});

        if (!Roles.GetRolesForUser("lelong37").Contains("Administrator"))
            Roles.AddUsersToRoles(new[] {"lelong37"}, new[] {"Administrator"});
    }
现在EF5将负责创建您的UserProfile表,在此之后,您将调用WebSecurity.InitializeDatabaseConnection仅向已创建的UserProfile表注册SimpleMembershipProvider,还告诉SimpleMembershipProvider哪个列是UserId和UserName。我还展示了一个示例,演示如何在Seed方法中添加用户、角色以及关联两者与自定义UserProfile属性/字段(例如用户的Mobile(号码)和IsSmsVerified)。
3-现在,当您从Package Manager Console运行update-database时,EF5将使用所有自定义属性来提供您的表格。
有关更多参考,请参见此文章和源代码: http://blog.longle.net/2012/09/25/seeding-users-and-roles-with-mvc4-simplemembershipprovider-simpleroleprovider-ef5-codefirst-and-custom-user-properties/

很好...这确实帮助我解决了一个非常困难的情况。 :) 关于此事的更多信息请查看:http://weblogs.asp.net/jgalloway/archive/2012/08/29/simplemembership-membership-providers-universal-providers-and-the-new-asp-net-4-5-web-forms-and-asp-net-mvc-4-templates.aspx - Leniel Maccaferri
6
假定你正在使用来自互联网模板的 DEMOWARE 代码。在真实的应用程序中,你需要在数据访问项目中设置 EF 依赖项,并且可能不希望它依赖于 WebMatrix 组件或任何 System.Web 组件。 - Thiago Silva
我同意,但是在你的数据访问项目中如何避免使用Webmatrix呢? - nportelli
我有一个问题,请问,我已经完成了一切工作,并成功创建了角色和用户,但是当我尝试将用户分配到角色时,我会出现异常,因为Users表为空,并且我的用户数据进入UserTable,所以究竟出了什么问题? - TheSM

15

他们通过SimpleMembership使得修改个人资料变得简单。 SimpleMembership使用的是Code First EF模型,用户资料定义在生成的AccountModels.cs文件中,该文件作为MVC 4的Internet模板的一部分。只需修改UserProfile类并在类定义中添加新字段即可。例如,添加一个用于电子邮件的字段可能如下所示:

[Table("UserProfile")]
public class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    public string UserName { get; set; }
    public string Email { get; set; }
}

以下是如何访问电子邮件字段的示例:

var context = new UsersContext();
var username = User.Identity.Name;
var user = context.UserProfiles.SingleOrDefault(u => u.UserName == username);
var email = user.Email;

在添加了电子邮件字段后,数据库的外观如下所示。

enter image description here

有一篇很好的博客介绍了 SimpleMembership 的一些变化。您还可以在此处找到有关自定义和种子 SimpleMembership 的更详细信息


另外,当我反编译WebSecurity.InitializeDatabaseConnection时,我发现它只处理了UserName和UserId。没有代码来处理额外的列。我认为你必须自己创建它们。 - PlanetWilson
我正在使用最新的 VS 2012 并构建 MVC 4,在使用互联网模板和默认 AccountController 启动新项目。在 AccountModel 的 UserProfile 类中添加新属性后,数据库没有为我的新属性生成字段。我已多次删除数据库并重复此过程,但我添加的新属性从未在数据库中创建。 - Quad Coders
suhendri - 你确定你正在查看正确的数据库吗?有两个,一个用于标准ASP.NET安全性,另一个用于SimpleMembership。没有代码示例和屏幕截图很难确定你遇到了什么问题。你可能需要打开自己的QA并提供详细信息以获得帮助。 - Kevin Junghans
有人可以帮忙更新Manage.cshtml视图+控制器,以便用户可以像上面的示例一样编辑自己的电子邮件吗? - firepol
看看这篇博客文章[http://kevin-junghans.blogspot.com/2013/02/adding-email-confirmation-to.html],它展示了如何在注册过程中添加电子邮件确认。这将向您展示如何在Register.cshtml中捕获电子邮件。相同的概念也适用于Manage.cshtml。 - Kevin Junghans
显示剩余5条评论

4
如果你在 accountcontroller 的第273行附近查看,你会找到这一行。
db.UserProfiles.Add(new UserProfile { UserName = model.UserName });

看起来,即使是OOTB,微软也正在按照您建议的方式使用EF进行更新。

我也正在寻找更新和访问这些属性的“正确”方法。

编辑:

这是我的解决方案(如果有人说有一种OOTB的方法来做到这一点,我会很高兴)。

在会话类中包装UserProfile(来自SimpleMembership的.NET实体)。

public static class sessionHelpers {
     public static UserProfile userProfile
        {
            get
            {
                if (HttpContext.Current.Session["userProfile"] != null)
                {
                    return HttpContext.Current.Session["userProfile"] as UserProfile; 
                }
                else
                {
                    using (UsersContext db = new UsersContext())
                    {
                        HttpContext.Current.Session["userInfo"] =
                        db.UserProfiles.Where(x => x.UserName == 
                            HttpContext.Current.User.Identity.Name).FirstOrDefault();

                   return db.UserProfiles.Where(x => x.UserName == 
                       HttpContext.Current.User.Identity.Name).FirstOrDefault();
                    }
                }
            }
            set { HttpContext.Current.Session["userProfile"] = value; }
        }
}

通过这个方法,你可以访问个人资料表格:

string foo = sessionHelpers.userProfile.FIELDNAME;

这里的 sessionHelpers 是我的包装类,该 if 块仅确保如果在当前会话中未设置它时访问它将尝试获取它。


2
嗯...我感觉这里有一些严重的代码异味...你正在将数据库访问代码与Web代码混合在一起。我强烈建议将所有实体框架引用重构为一个独立的数据访问项目,然后使用存储库模式允许调用者检索应用程序的数据。 - Thiago Silva
使用这种模式,您如何确保对配置文件的更改被写回数据库? - Eric J.
我会将会话中的内容转换为UserProfile,而不是使用as关键字。如果您意外地放入其他类型,您的getter将只返回* null *。最好立即失败,而不是尝试诊断由空UserProfile引起的下游问题。 - Eric J.
代码使用相同的查询两次查询数据库。虽然查询可能已被缓存,但仍会增加额外的负载。 - Eric J.

1

你需要将它们添加到数据库中(按照说明完成)

将它们添加到视图中(编辑、添加、删除和查看),除非修改过

将它们添加到你的用户资料模型中

然后它就会起作用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接