我的代码经历了一次令人难以置信的变化,以便让mutlitple复选框起作用。我取消了我试图用来循环查看View上复选框的formsCollection。我在Controller和View中都在循环中使用了很多循环,我不再关心“关注点分离”或任何关于MVC的现代事物。在MS Access中,您可以将一大堆功能集中在一行中,这使得它不可读但有效。我总是分散逻辑以理解它并逐步完成它。我可能正在使用一种sophomoric方法来应对这个MVC 6的新现代世界,但我并不在意。我可以继续使用Roles废话实际上用CRUD做一些事情。我也不想让Stephen Muecke失望,因为我的大部分MVC知识都是他对我的问题的关注汇编。用Bing搜索后,我发现 this link about checkboxes 非常简单且乐于助人。我的大部分观点已经建立。我的时间用于显示已经检查过的用户角色。所以现在,我有一个View和Edit表单,允许通过复选框为所选用户添加或删除角色。不漂亮,但非常好吃恕我直言。 (“MVC6”是我的项目的名称,而不是内置名称)。我没有必要使用Owin依赖项。我必须添加的依赖性是启用会话,因此我可以发送TempData [“Status”]消息。其他一切都在“盒子”之外。
查看:
@using MVC6.Models
@using Microsoft.AspNet.Http
@model Microsoft.AspNet.Identity.EntityFramework.IdentityUser
@{
ViewBag.Title = "Edit User";
var roles = new MVC6Context().Roles.ToList();
var usersroles = new MVC6Context().UserRoles.ToList();
}
<ol class="breadcrumb">
<li>@Html.ActionLink("Administration", "Index", "Admin")</li>
<li>@Html.ActionLink("Users", "Index", "UserManagement")</li>
<li>Edit User</li>
</ol>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary()
@Html.HiddenFor(model => model.Id)
@Html.HiddenFor(model => model.Email)
<h3>Username:</h3>
<div class="form-control">
@Model.Email
</div>
<h3>Roles:</h3>
if (roles.Any())
{
<div >
@foreach (var role in roles)
{
bool isinrole = false;
@foreach (var ur in usersroles)
{
@if (Model.Id == ur.UserId) //usersroles returns all roles for all users
{
@if(ur.RoleId == role.Id)
{
isinrole = true;
}
}
}
@if (isinrole)
{
<input type="checkbox" name="checkRoles" value="@role.Name" checked />
@Html.Label(role.Name)
}
else
{
<input type="checkbox" name="checkRoles" value="@role.Name"/>
@Html.Label(role.Name)
}
<br/>
}
</div>
<br />
<button type="submit" class="btn btn-default">Save</button> <span style="color:red;">@if (@TempData["Status"] != null){@TempData["Status"]}</span>
}
else
{
<div class="alert alert-info" role="alert">
No roles available
</div>
}
<br />
控制器
[HttpGet]
public ActionResult Edit(string userId)
{
return View(context.Users.FirstOrDefault(u => u.Id == userId));
}
[HttpPost]
public async Task<ActionResult> Edit(string[] checkRoles, string userID)
{
var UserManager = _serviceProvider.GetRequiredService<UserManager<ApplicationUser>>();
var RoleManager = _serviceProvider.GetRequiredService<RoleManager<IdentityRole>>();
var allRoles = RoleManager.Roles.ToList();
var user = await UserManager.FindByIdAsync(userID);
var usersRoles = await UserManager.GetRolesAsync(user);
//LOOP THROUGH ROLES
foreach (var item in allRoles)
{
bool wasChecked = false;
//ALL CHECKBOXES THAT WERE CHECKED
foreach (var roleChecked in checkRoles)
{
if (item.Name == roleChecked)
{
wasChecked = true;
}
}
//ALL CHECKBOXES THAT WERE NOT CHECKED
if (wasChecked == false)
{
//IF USER HAS ROLE, REMOVE IT
if (await UserManager.IsInRoleAsync(user, item.Name))
{
await UserManager.RemoveFromRoleAsync(user, item.Name);
}
}
else //IF CHECK BOX CHECKED THEN ADD ROLE TO USER
{
await UserManager.AddToRoleAsync(user, item.Name);
}
}
TempData["Status"] = "Roles are updated as of <b>" + DateTime.Now.ToShortTimeString() + "</b>";
return View(user);
}
对我这样的新手来说,有什么可以帮助AspNetUserRoles表有2列,UserId和RuleId。这是一种“多对多”的关系。在上面的代码中,一旦我获得了有关我想编辑的用户的所有信息,并从多对多中获取所有用户的角色,那么我可以迭代它来添加或删除一行。对View来说有点相同。我知道这些东西可能会被重构,但它在我们谈话时正在做生意。我很乐意给那些甚至稍微重构一下的人一个接受的答案(但不会把它变成疯狂的科学家,所有应有的尊重)。