简体   繁体   中英

Simple way to store extra user information in MVC 3?

Playing around for the first time with ASP.NET MVC 3 and really struggling to do what should be extremely simple.

I'm having a user register using the built-in membership functionality, but I want to store their first name and last name as well, which are not properties that are provided by default.

I cannot figure out how to add these properties to the MembershipUser class (if that's even the right class, it's hard to really figure out what's going on here). I also tried creating a new "UserDetails" model, but couldn't figure out how to link that to the regular user table using the UserID as a foreign key.

What is the correct approach to storing extra user information in an ASP.NET MVC 3 Web Application using a Code First approach? I must be doing something wrong here because this has to be brain dead simple. I'm seeing stuff about Custom Profile Providers that just seems so excessive for such basic functionality.

Anyone able to point me in the right direction? Thanks.

You need to add those properties in the RegisterModel as below:

 public class RegisterModel
    {
        [Required]
        [Display(Name = "User name")]
        public string UserName { get; set; }

        [Required]
        [DataType(DataType.EmailAddress)]
        [Display(Name = "Email address")]
        public string Email { get; set; }

        [Required]
        [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
        [DataType(DataType.Password)]
        [Display(Name = "Password")]
        public string Password { get; set; }

        [DataType(DataType.Password)]
        [Display(Name = "Confirm password")]
        [System.Web.Mvc.Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
        public string ConfirmPassword { get; set; }
       //Put annotatons as needed
        public string FirstName {get;set;}
        public string LastName {get;set;}
    }

After this , you will need to put those details in the database using the Register method in AccountController . This can be managed by taking the UserId from Membership and putting the extra details in a completely different table against this UserId in database.This table can be as below:

public class ExtendedUser
{
    [Key]
    public Guid UserId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

So your Register method, that is annoted with [HttpPost] changes to the following to store the data in above table.

[HttpPost]

public ActionResult Register(RegisterModel model)
{
    if (ModelState.IsValid)
    {
        // Attempt to register the user
        MembershipCreateStatus createStatus;
        Membership.CreateUser(model.UserName, model.Password, model.Email, null, null, true, null, out createStatus);

        if (createStatus == MembershipCreateStatus.Success)
        {
            FormsAuthentication.SetAuthCookie(model.UserName, false /* createPersistentCookie */);
           //Get UserId for registered user
            var UserId = (Guid)Membership.GetUser(model.UserName).ProviderUserKey;
            ExtendedUser extrainfo = new ExtendedUser();
            extrainfo.UserId = UserId;
            extrainfo.FirstName= model.FirstName;
            extrainfo.LastName= model.LastName;
            //Add this info to database
            db.ExtendedUsers.Add(extrainfo);
            db.SaveChanges();
            return RedirectToAction("Index", "Home");
        }
        else
        {
            ModelState.AddModelError("", ErrorCodeToString(createStatus));
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

Offcourse, you will need to add this new table the class inherited from DbContext class as below:

 public class YourContext: DbContext
    {
        public DbSet<ExtendedUser> ExtendedUsers{ get; set; }
    }

hussh...and you are done.

Edit :

Microsoft has done this in a different way at How to: Implement a Custom Membership User , but they are missing something in there.But you can have a look at it.

To be honest, I would not use the default Membership tools, as the database schema consists almost entirely of BLOB fields, and the default providers assume you want to use their embedded ADO logic. Since you mentioned Code First, I assume you are (or want to be) using Entity Framework. It's not terribly hard to write a custom Membership provider that can leverage EF (or any other data-access tool, for that matter).

If you need direction, you can find the implementations I use for both the Membership and Role providers of my personal site here: https://github.com/tiesont/Monkey.CMS/tree/master/Monkey.Web/Core/Providers - and yes, custom providers are overkill, since you can see by my implementations that most of the abstract base class methods don't need to be implemented to get a working provider.

This isn't an MVC-specific answer, but ASP.Net Membership providers are designed for straightforward authorization scenarios and not attaching additional information. Per the MSDN docs on this : "Membership can also be integrated with user profile properties to provide application-specific customization that can be tailored to individual users."

You'll want to create a profile schema that contains properties for the first and last name , maybe something like this:

<profile defaultProvider="AspNetSqlProfileProvider">
  <properties>
     <add name="FirstName" type="System.String" />
     <add name="LastName" type="System.String" />
  </properties>
</profile>

and then you can reference their profile details from the HTTP context User property .

Also see Walkthrough: Maintaining Web Site User Information with Profile Properties

Good luck!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM