0

I am trying to add roles to my existing Identity framework. For that part I have modified my account controller as follows:

   public ActionResult Register()
    {
         List<SelectListItem> list = new List<SelectListItem>();
         foreach (var role in RoleManager.Roles)
         list.Add(new SelectListItem() { Value = role.Name, Text = role.Name });
         ViewBag.Roles = list;



        return View();
    }

Here is my Post Register method. I have repopulated it with User roles .

             //
    // POST: /Account/Register
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> Register(RegisterViewModel model)
    {
        if (ModelState.IsValid)
        {
            if (ModelState.IsValid)
            {
                var user = new ApplicationUser { Email = model.Email };
                var result = await UserManager.CreateAsync(user, model.Password);
                if (result.Succeeded)
                {
                    result = await UserManager.AddToRoleAsync(user.Id, model.UserRoles);
                    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>");   
                    //Assign Role to user Here      

                    //await this.UserManager.AddToRoleAsync(user.Id, model.UserRoles.ToString());

                    //Ends Here    
                    return RedirectToAction("Index", "Users");
                }
                List<SelectListItem> list = new List<SelectListItem>();
                foreach (var role in RoleManager.Roles)
                    list.Add(new SelectListItem() { Value = role.Name, Text = role.Name });
                ViewBag.Roles = list;

                AddErrors(result);
            }

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

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

And Register View Model as

         public class RegisterViewModel
{
    public int Id { get; set; }

    [Display(Name = "User Role")]
    public string UserRoles { get; set; }

    [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; }
}

And Register.cshtml as

        <div class="form-group">
    @Html.LabelFor(m => m.UserRoles, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
       @Html.DropDownListFor(m => m.UserRoles, new SelectList(ViewBag.Roles, "Value", "Text"),"Select a Role", new {@class = "form-control" })
    </div>
</div>

When I click the register button. An exception is thrown saying that value cannot be null, parameter name items.

RoleViewModel contains the following lines

          public class RoleViewModel
{
    public RoleViewModel() { }
    public RoleViewModel(ApplicationRole role)
    {
        Id = role.Id;
        Name = role.Name;
    }
    public string Id { get; set; }

    public string Name { get; set; }

}
7
  • The error means that ViewBag.Roles is null because you did not repopulate it in the post method (which you did not show) before you return the view. And as a side note, using new SelectList(...) in the view to create another identical IEnumerable<SelectListItem> is pointless extra overhead Commented Aug 5, 2018 at 7:53
  • @StephenMuecke I have re edited it. And now it says Name cannot be null or empty. I am new to MVC architecture and need a thorough understanding of what is going on. Commented Aug 5, 2018 at 8:15
  • 1
    Yes you need to repopulate the SelectList before calling return View();. But you are using a view model so why in the world are you using ViewBag - add an IEnumerable<SelectListItem> Roles property to your model (refer this answer for a typical example). And why do you have if (ModelState.IsValid) twice (remove one of them) Commented Aug 5, 2018 at 8:17
  • I have removed if(ModelState.IsValid). But now it says Name cannot be null or empty. Please tell me how to do it with ViewBag approach. Commented Aug 5, 2018 at 8:37
  • You still need if(ModelState.IsValid) - but just once :). And what line of code throws that error (its has nothing to do with the code associated with generating the dropdownlist) Commented Aug 5, 2018 at 8:40

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.