Search code examples
asp.net-mvcsimplemembership

Simple Membership WebSecurity.CreateUserAndAccount give duplicate UserId Error


Using MVC 4, Simplemembership

I am building a web application for corporate use and hence don't want the out of the box MVC 4 template functionality to allow users to Register. Instead I want a Create User view that allows only an Administrator to access and then create users. I was hoping I could just change the security on the register controller and then have the currently logged in user create users using the existing Register View...no dice.

Here is the code in the controller. I have not changed it from the template:

// POST: /Account/Register

        [HttpPost]
        //[AllowAnonymous]
        [ValidateAntiForgeryToken]
        public ActionResult Register(RegisterModel model)
        {
            if (ModelState.IsValid)
            {
                // Attempt to register the user
                try
                {
                    WebSecurity.CreateUserAndAccount(
                        model.UserName,
                        model.Password,
                        new { FirstName = model.FirstName, LastName = model.LastName, Email = model.Email },
                        false
                    );
                    WebSecurity.Login(model.UserName, model.Password);
                    return RedirectToAction("Index", "Home");
                }
                catch (MembershipCreateUserException e)
                {
                    ModelState.AddModelError("", ErrorCodeToString(e.StatusCode));
                }
            }

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

When a currently logged in user attempts to create a new user via this, you get the error (@ line 86):

The INSERT statement conflicted with the FOREIGN KEY constraint "FK_UserProfile_webpages_Membership". The conflict occurred in database "OTIS", table "dbo.webpages_Membership", column 'UserId'.
The statement has been terminated.

Line 84:                 try
Line 85:                 {
Line 86:                     WebSecurity.CreateUserAndAccount(
Line 87:                         model.UserName,
Line 88:                         model.Password,

Hwre is the UserProfile class

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

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

        [Required]
        [Display(Name = "First Name")]
        public string FirstName { get; set; }

        [Required]
        [Display(Name = "Last Name")]
        public string LastName { get; set; }

        [Display(Name = "Email")]
        public string Email { get; set; }
    }

WebSecurity.CurrentUserID is populated with the currently logged in user, which I assume is what is causing the problem. What is the correct way to achieve this using the simplemembership provider?

EDIT: I've tried moving this back to allowing anonymous users to register so the WebSecurity.CurrentUserID is -1 when I debug it and I still get the same error. If the UserId field in the class is decorated with the attribute [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)], how could a duplicate key be being generated?


Solution

  • Finally got back to this issue. The problem for me was that my database relationships were corrupted. The UserProfile table to Membership table foreign key constraints were set such that the UserId column was noted as the primary key in BOTH tables. As such, when it tried to add a row in UserProfile, it's newly generated ID did not exist in Membership, which caused the error. Simply deleting the relationship and recreating correctly such that UserProfile.UserId was the primary fixed it.