如何在MVC中使用自定义成员身份添加更多自定义字段?

7

我已经覆盖了会员方法来创建自定义会员。

在账户模型中,我覆盖了CreateUser方法:

public override MembershipUser CreateUser(string username, string password,
    string email, string passwordQuestion, string passwordAnswer,
    bool isApproved, object providerUserKey, out MembershipCreateStatus status)
{
    ValidatePasswordEventArgs args = new ValidatePasswordEventArgs(
        username, password, true);
    OnValidatingPassword(args);

    if (args.Cancel)
    {
        status = MembershipCreateStatus.InvalidPassword;
        return null;
    }

    if (RequiresUniqueEmail && GetUserNameByEmail(email) != "")
    {
        status = MembershipCreateStatus.DuplicateEmail;
        return null;
    }

    MembershipUser u = GetUser(username, false);
    if (u == null)
    {
        UserRepository _user = new UserRepository();

        // Here I call my new method which has fields I've created in the
        // User table; I'm using entity framework.    
        _user.CreateUser(username, password, email);
        status = MembershipCreateStatus.Success;
        return GetUser(username, false);
    }
    else
    {
        status = MembershipCreateStatus.DuplicateUserName;
    }

    return null;
}

public MembershipUser CreateUser(string username, string password,
    string email)
{
    using (CustomMembershipDB db = new CustomMembershipDB())
    {
        User user = new User();
        user.UserName = username;
        user.Email = email;
        user.PasswordSalt = CreateSalt();
        user.Password = CreatePasswordHash(password, user.PasswordSalt);
        user.CreatedDate = DateTime.Now;
        user.IsActivated = false;
        user.IsLockedOut = false;
        user.LastLockedOutDate = DateTime.Now;
        user.LastLoginDate = DateTime.Now;

        //Generate an email key
        // user.NewEmailKey = GenerateKey();

        db.AddToUsers(user);
        db.SaveChanges();

        //send mail
        // SendMail(user);

        return GetUser(username);
    }
}

现在我需要添加两个字段,如名字和姓氏,但是我该如何将它们传递给上面的方法呢?

由于重写方法CreateUser如果添加像名字和姓氏这样的参数会导致错误 :(


1
你真的不应该尝试向MembershipUser类添加字段。如果你想要存储FirstName、LastName等信息,那么Profile和ProfileProvider(在web.config中的'<profile>')就是为此而设计的。 - danludwig
我该如何使用它,请给我任何链接? - Neo
这是您的链接:https://www.google.com?q=asp.net+profile+provider - danludwig
您可以在MVC中使用ProfileProvider,就像您可以使用MembershipProvider和RoleProvider一样。Profiles是ASP.NET而不是WebForms。 - danludwig
4个回答

5

你能建议我在上面的代码中把我的 firstname 属性放在哪里吗? - Neo

1
你可以保留AspNetUsers表不变,创建一个新表来存储额外信息(与原始表相关联)。这样,您就不会破坏成员提供程序中的任何现有代码。
原始的AspNetUsers表具有: [Id],[Email],[EmailConfirmed],[PasswordHash],[SecurityStamp],[PhoneNumber],[PhoneNumberConfirmed],[TwoFactorEnabled],[LockoutEndDateUtc],[LockoutEnabled],[AccessFailedCount],[UserName]
用于存储额外数据的新表可以具有例如: [Id],[UserId],[DateOfBirth],[Biography]等。 其中[UserId]是对AspNetUsers表的外键。
这种方法的一个优点是,您可以创建多种类型的用户,每种类型在不同的表中存储其相关信息,而常见数据仍在原始表中。
如何实现:
  1. 首先更新RegisterViewModel,以包含您想要的额外数据。
  2. 更新Account Controller中的Register方法,以下是已更新的原始方法,其中包含插入新个人资料数据的代码:

    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model)
    {
        if (ModelState.IsValid)
        {
            var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
            IdentityResult result = await UserManager.CreateAsync(user, model.Password);
            if (result.Succeeded)
            {
                // 新代码开始 ----------------------------------------
    
                // 获取新插入用户的Id
                int userId = user.Id; // 获取新插入用户的Id
    
                // 创建一个引用userId的个人资料
                AddUserProfile(userId, model);
    
                // 新代码结束 ----------------------------------------
    
                await SignInAsync(user, isPersistent: false);
                return RedirectToAction("Index", "Home");
            }
            else
            {
                AddErrors(result);
            }
        }
        return View(model);
    }
    
  3. 按照您的意愿实现AddUserProfile(int userId, RegisterViewModel model)方法。您将从model对象中收集额外的数据以及userId,并将新的个人资料对象保存在DB中。

0

创建一个继承自MembershipProvider并实现方法的类,这些方法通过调用SqlMembershipProvider是相同的,但可以更改您想要不同功能的其他方法。

看一下这篇文章:ASP.NET 2.0的SQLite 3.0的成员身份和角色提供程序

更新:

ASP.NET中的Membership系统旨在为许多Web应用程序(请参阅本系列文章的第1部分以深入了解Membership)所面临的用户帐户工作创建标准化的API。虽然Membership系统涵盖了核心用户相关属性 - 用户名、密码、电子邮件地址等等 - 但往往需要捕获每个用户的其他信息。不幸的是,这些附加信息在应用程序之间可能有很大的差异。

Microsoft没有将附加用户属性添加到Membership系统中,而是创建了Profile系统来处理附加用户属性。Profile系统允许在Web.config文件中定义其他特定于用户的属性,并负责将这些值持久化到某些数据存储中。

参考资料:审查ASP.NET的成员身份、角色和配置文件 - 第6部分


你能建议我在上面的代码中把我的 firstname prop 放在哪里吗? - Neo
如果您阅读了那篇文章,它会向您展示扩展ASP.NET Membership功能的更简单方法。 - Jahan Zinedine
但是如果你想使用这段代码,你应该在Membership Provider创建用户之后的方法外部更新用户行。 - Jahan Zinedine

0
这是我完成类似任务的方法。我在 CreateUserWizard 中添加了 onCreatedUser 事件,当您按下 CreateUser 按钮时,它会加载该方法。
protected void CreateUserWizard1_CreatedUser(object sender, EventArgs e)
    {
        MembershipUser mu = Membership.GetUser(CreateUserWizard1.UserName);
        int idOfInsertedUser = (int)mu.ProviderUserKey;

        TextBox tb1 = (TextBox)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("FirstName";
        string firstName= tb1.Text;
        TextBox tb2 = (TextBox)CreateUserWizard1.CreateUserStep.ContentTemplateContainer.FindControl("LastName";
        string lastName= tb2.Text;  

// now you have values of two more fields, and it is time to call your Database methods for inserting them in tables of choice...
    }

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