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

}
  • 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` is pointless extra overhead –  Aug 05 '18 at 07: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. – Muhammad Shahid Aug 05 '18 at 08: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 Roles` property to your model (refer [this answer](https://stackoverflow.com/questions/38921483/value-cannot-be-null-parameter-name-items-in-dropdown-list-asp-net-mvc5) for a typical example). And why do you have `if (ModelState.IsValid)` twice (remove one of them) –  Aug 05 '18 at 08: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. – Muhammad Shahid Aug 05 '18 at 08: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) –  Aug 05 '18 at 08:40
  • Yes the code does not throw any exception or error . It looks to me as a validation message, but I don't have a field called Name in the table, in The model I have created a property Name model name is RoleViewModel – Muhammad Shahid Aug 05 '18 at 08:45
  • Sorry, I have no idea what you are referring to. There is nothing in the code you have shown that causes that and I do not know what changes you have made. I suggest you ask a new question with the relevant details. –  Aug 05 '18 at 08:51

0 Answers0