Добавление роли при создании нового пользователя

#c# #asp.net #asp.net-core #asp.net-identity

#c# #asp.net #asp.net-ядро #asp.net-идентификатор

Вопрос:

С помощью следующего кода мне удалось добавить выпадающее поле на страницу создания пользователя, где роль может быть назначена при создании нового пользователя. Я сделал это, используя a ViewBag , но я чувствую, что это не самое элегантное решение, поэтому я пытаюсь изменить его, используя a List<SelectListItem> RolesList в my CreateUserViewModel . Таким образом, я мог бы избавиться от ViewBags

Я не уверен, как подойти к этому, поскольку я все еще новичок в ViewModels, я прокомментировал свое текущее решение в HttpPost Create() методе. Любая помощь будет принята с благодарностью!

введите описание изображения здесь

AccountController.cs

     [HttpGet]
    public ActionResult Create()
    {
        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();
    }

    [HttpPost]
    public async Task<IActionResult> Create(CreateUserViewModel user)
    {
        // var UserList = user.RolesList;
        // foreach (var role in roleManager.Roles)
        // {
        //  UserList.Add(new SelectListItem(){Value = role.Name, Text = role.Name});
        // }

        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;
        if (ModelState.IsValid)
        {
            var appUser = new ApplicationUser
            {
                UserName = user.Name,
                Email = user.Email
            };
            var result = await userManager.CreateAsync(appUser, user.Password);
            if (result.Succeeded)
            {
                await userManager.AddToRoleAsync(appUser, user.RoleName);

                return RedirectToAction("Index");
            }
        }
        return View(user);
    }
 

CreateUserViewModel.cs

 public class CreateUserViewModel
{
    [Required]
    public string Name { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string Password { get; set; }

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

    public List<SelectListItem> RolesList { get; set; }
 

Create.cshtml

 @model ViewModels.CreateUserViewModel
  
<h1>Create User</h1>

<a asp-action="Index" class="btn btn-secondary">Back</a>
<div asp-validation-summary="All" class="text-danger"></div>
  
<form method="post">
    <div class="form-group">
        <label asp-for="Name"></label>
        <input asp-for="Name" class="form-control" />
    </div>
    <div class="form-group">
        <label asp-for="Password"></label>
        <input asp-for="Password" class="form-control" />
    </div>
    <div class="form-group">
        //@Html.DropDownListFor(m => m.RoleName, new SelectList(Model.RolesList, "Value", "Text"), new { @class = "form-control" })
        @Html.DropDownListFor(m => m.RoleName, new SelectList(ViewBag.Roles,"Value", "Text"), new { @class = "form-control"})
    </div>
    <button type="submit" class="btn btn-primary">Create</button>
</form>
 

Ответ №1:

Если вы инициализируете свою модель представления в методе get и возвращаете ее в представление, вы можете просто избежать viewbag. Хотя мы можем провести некоторую оптимизацию кода, чтобы избежать попаданий в БД, но что-то вроде этого должно сработать.

 
[HttpGet]
        public ActionResult Create()
        {
            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; // this we can eliminate now !

            return View(new CreateUserViewModel
            {
                RolesList = list // this should populate the dropdown in your example
            });

        }