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