1

I am working on an application where students get to select their department, and role while registering to the site. I was able to add the option to select Department and role to the registration form. Actually, the DropDownList for the Department is being Populated from a Department Table in the database. but When I try to register a user after filling out the form, I get this error message

Server Error in '/' Application. The INSERT statement conflicted with the FOREIGN KEY constraint "FK_dbo.AspNetUsers_dbo.Departments_DepartmentID". The conflict occurred in database "aspnet-AptechAPP-20180514123201", table "dbo.Departments", column 'DepartmentID'. The statement has been terminated.

Below is the Screen shot of my RegisterViewModel

public class RegisterViewModel
{
    [Required]
    [EmailAddress]
    [Display(Name = "Email")]
    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")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
    public int DepartmentID { get; set; }
    public IEnumerable<System.Web.Mvc.SelectListItem> DepartmentList
    {
        get; set;
    }
}

My RegisterViewController

 // GET: /Account/Register
    [AllowAnonymous]
    public ActionResult Register()
    {
        ViewBag.Name = new SelectList(context.Roles.Where(u => !u.Name.Contains("Admin"))
            .ToList(), "Name", "Name");
        RegisterViewModel model = new RegisterViewModel();
        ConfigureRegisterViewModel(model);
        return View(model);
    }

    //
    // POST: /Account/Register
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model)
    {
        if (!ModelState.IsValid)
        {
            ConfigureRegisterViewModel(model);
            return View(model);
        }

        var user = new ApplicationUser { UserName = model.Email, Email = model.Email, DepartmentID = model.DepartmentID };


        var result = await UserManager.CreateAsync(user, model.Password);
        if (result.Succeeded)
        {
            await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false);

            // For more information on how to enable account confirmation and password reset please visit http://go.microsoft.com/fwlink/?LinkID=320771
            // Send an email with this link
            // string code = await UserManager.GenerateEmailConfirmationTokenAsync(user.Id);
            // var callbackUrl = Url.Action("ConfirmEmail", "Account", new { userId = user.Id, code = code }, protocol: Request.Url.Scheme);
            // await UserManager.SendEmailAsync(user.Id, "Confirm your account", "Please confirm your account by clicking <a href=\"" + callbackUrl + "\">here</a>");

            return RedirectToAction("Index", "Home");
        }
        ViewBag.Name = new SelectList(context.Roles.Where(u => !u.Name.Contains("Admin"))
            .ToList(), "Name", "Name");

        AddErrors(result);


        // If we got this far, something failed, redisplay form
        ConfigureRegisterViewModel(model);
        return View(model);
    }
    private void ConfigureRegisterViewModel(RegisterViewModel model)
    {
        IEnumerable<Department> departments = db.Departments.OrderBy(u => u.DepartmentName).ToList();
        model.DepartmentList = departments.Select(a => new SelectListItem
        {
            Value = a.DepartmentID.ToString(),
            Text = a.DepartmentName.ToString()
        });


    }

My DepartmentViewModel

 public class Department
{
    public virtual int DepartmentID { get; set; }
    public virtual string DepartmentName { get; set; }
}

My IdentityModel

public class ApplicationUser : IdentityUser
{
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
    {
        // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
        var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
        // Add custom user claims here
        return userIdentity;
    }
     public int DepartmentID { get; set; }
    public virtual Department Department
    {
        get; set;
    }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

Register.Cshtml

 <div class="form-group">
    @Html.LabelFor(model => model.DepartmentID, new { @class = "control-label col-md-2" })
    <div class="col-md-10">
        @Html.DropDownListFor(m => m.DepartmentID, Model.DepartmentList, "Please select", new { @class = "form-control" })

    </div>
</div>
<div class="form-group">
    @Html.Label("user Role", new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @*@Html.DropDownList("Name")*@
        @Html.DropDownList("UserRoles", (SelectList)ViewBag.Name, " ")
    </div>
</div>
CodeNotFound
  • 22,153
  • 10
  • 68
  • 69
Engr Jboy
  • 11
  • 4
  • Are you sure that you are getting departments list with correct text and values? – Dani May 14 '18 at 15:12
  • @Dani. Sure i guess i am.. cause i can actually select from list of departments i created in my department table when am filling out the form. but when it tries to post, it gives me an error – Engr Jboy May 14 '18 at 15:25
  • Can you post view code please? – Dani May 14 '18 at 15:28
  • @Dani i guess the problem is from my Register Post Method or from my IdentityModel.. – Engr Jboy May 14 '18 at 15:30
  • @Dani I have updated my code. Please help me go through it. – Engr Jboy May 14 '18 at 15:38
  • Try to change in view `@Html.DropDownListFor(m => m.DepartmentID, Model.DepartmentList, "Please select", new { @class = "form-control" }) ` to this `@Html.DropDownListFor(m => m.DepartmentID, new SelectList(Model.DepartmentList, "DepartmentID", "DepartmentName"), "Please select", new { @class = "form-control" })` – Dani May 14 '18 at 15:50
  • @Dani i just did that now, and when i try to load the Register.cshtml, it gave me another error DataBinding: 'System.Web.Mvc.SelectListItem' does not contain a property with the name 'DepartmentID'. – Engr Jboy May 14 '18 at 16:04
  • Ok when i get home i look at it !!! – Dani May 14 '18 at 16:08
  • @Dani thanks Boss I will really appreciate that.. You can take your time and go through my work am just new to MVC5 so the whole concept is still confusing me a bit – Engr Jboy May 14 '18 at 16:32
  • @EngrJboy the reason you got that error with Dani's code is because of this line `new SelectList(Model.DepartmentList, "DepartmentID", "DepartmentName")` it should be `new SelectList(Model.DepartmentList, "Value", "Text")`. Regardless of that you shouldn't need that the way you have it originally is fine because you are using `SelectListItem`. I would suggest you put a breakpoint on your POST and see what you are getting in your model. Most likely your `DepartmentId` is returning back 0. – penleychan May 14 '18 at 16:57
  • @EngrJboy can you insert the values manually using sql query into the AspNetUsers table in Sql Management studio and test it. The issue is with the foreign key references https://stackoverflow.com/questions/2965837/insert-statement-conflicted-with-the-foreign-key-constraint-sql-server – giri-webdev May 15 '18 at 09:26

2 Answers2

0

The target table you are inserting data into has a foreign key relationship with Department ID in another table. Before data can be inserted, the Department ID must exist in the other table first. Is a valid department ID selected? What is the Department ID when selected? Does that department ID exist in the other table?

var user = new ApplicationUser 
{ UserName = model.Email, 
Email = model.Email, 
DepartmentID = model.DepartmentID //here?
};
L0uis
  • 703
  • 5
  • 8
  • @penleychan thanks for your idea, but actually, am porpulating the department DropdownList in my Registration Form from a department table that already exist in my StudentContextDB Database. and the table contains some departments already. Everything seams to be working fine except that after filling out the form, and selecting a department from the DropdownList, When i click on submit, it gives me the error. – Engr Jboy May 14 '18 at 19:35
0

I think that the problem is that you are not building a correct Dropdownlist in View, so when form is submitted, the application is triying to insert null value in DepartmentId of the user and it throws an exception because is an invalid FK.

In view, change this:

@Html.DropDownListFor(
m => m.DepartmentID, 
Model.DepartmentList, 
"Please select", 
new { @class = "form-control" })

To this:

@Html.DropDownListFor(
    m => m.DepartmentID,
    new SelectList(Model.DepartmentList, "Value", "Text"), 
    "Please select", 
    new { @class = "form-control" })
Dani
  • 1,825
  • 2
  • 15
  • 29