我需要使用实体框架代码优先方法将用户链接到ASP.NET MVC 5和ASP.NET身份的帮助。
这里的用例是,当我创建一个用户时,我需要在ReportsTo下拉列表中选择一个用户,该列表显示该用户的名字和姓氏,并将所选用户的ID保存在Identity User表的ReportsTo列中。该用户列表必须是数据库中现有Identity用户的列表。
我实现了各种主题,并设法获得了一个下拉列表,以与Identity用户一起在我的用户创建和编辑视图中显示。它将ID保存在数据库的ReportsTo列中,但是当我编辑用户时,ReportsTo字段不会将ID保存在数据库中,除非我再次在下拉列表中进行相同的选择(它将用如果我不再进行选择(因为它不会在编辑视图中加载以前保存的值),则显示为空白),然后在详细信息页面和用户列表中,将ReportsTo保存的用户显示为GUID。
在我的用户控制器中:
public UserController()
{
using (var userList = new ApplicationDbContext())
{
ViewBag.ReportsTo = userList.Users.Select(user => new SelectListItem { Text = user.FirstName + " " + user.LastName, Value = user.Id }).ToList();
}
}
public ActionResult Create()
{
// Show a list of available groups:
ViewBag.GroupsList =
new SelectList(this.GroupManager.Groups, "Id", "Name");
return View();
}
[HttpPost]
public async Task<ActionResult> Create(RegisterViewModel userViewModel, params string[] selectedGroups)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
UserName = userViewModel.Email,
FirstName = userViewModel.FirstName,
LastName = userViewModel.LastName,
ReportsTo = userViewModel.ReportsTo,
OfficeNumber = userViewModel.OfficeNumber,
CellNumber = userViewModel.CellNumber,
Email = userViewModel.Email
};
var adminresult = await UserManager
.CreateAsync(user, userViewModel.Password);
//Add User to the selected Groups
if (adminresult.Succeeded)
{
if (selectedGroups != null)
{
selectedGroups = selectedGroups ?? new string[] { };
await this.GroupManager
.SetUserGroupsAsync(user.Id, selectedGroups);
}
return RedirectToAction("Users");
}
}
ViewBag.Groups = new SelectList(
await RoleManager.Roles.ToListAsync(), "Id", "Name");
return View();
}
public async Task<ActionResult> Edit(string id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var user = await UserManager.FindByIdAsync(id);
if (user == null)
{
return HttpNotFound();
}
// Display a list of available Groups:
var allGroups = this.GroupManager.Groups;
var userGroups = await this.GroupManager.GetUserGroupsAsync(id);
var model = new EditUserViewModel()
{
Id = user.Id,
Email = user.Email,
FirstName = user.FirstName,
LastName = user.LastName,
ReportsTo = user.ReportsTo,
OfficeNumber = user.OfficeNumber,
CellNumber = user.CellNumber
};
foreach (var group in allGroups)
{
var listItem = new SelectListItem()
{
Text = group.Name,
Value = group.Id,
Selected = userGroups.Any(g => g.Id == group.Id)
};
model.GroupsList.Add(listItem);
}
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(
[Bind(Include = "Email,Id,FirstName,LastName,ReportsTo,OfficeNumber,CellNumber")] EditUserViewModel editUser,
params string[] selectedGroups)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindByIdAsync(editUser.Id);
if (user == null)
{
return HttpNotFound();
}
// Update the User:
user.UserName = editUser.Email;
user.Email = editUser.Email;
user.FirstName = editUser.FirstName;
user.LastName = editUser.LastName;
user.ReportsTo = editUser.ReportsTo;
user.OfficeNumber = editUser.OfficeNumber;
user.CellNumber = editUser.CellNumber;
await this.UserManager.UpdateAsync(user);
// Update the Groups:
selectedGroups = selectedGroups ?? new string[] { };
await this.GroupManager.SetUserGroupsAsync(user.Id, selectedGroups);
return RedirectToAction("Users");
}
ModelState.AddModelError("", "Something failed.");
return View();
}
我的EditUserViewModel:
public class EditUserViewModel
{
public EditUserViewModel()
{
this.RolesList = new List<SelectListItem>();
this.GroupsList = new List<SelectListItem>();
}
public string Id { get; set; }
[Required(AllowEmptyStrings = false)]
[Display(Name = "Email")]
[EmailAddress]
public string Email { get; set; }
public string FirstName { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
[Display(Name = "Reports To")]
public string ReportsTo { get; set; }
[Display(Name = "Office Number")]
public string OfficeNumber { get; set; }
[Display(Name = "Cell Number")]
public string CellNumber { get; set; }
[Display(Name = "ProfilePicture")]
public byte[] ProfilePicture { get; set; }
public ICollection<SelectListItem> RolesList { get; set; }
public ICollection<SelectListItem> GroupsList { get; set; }
}
我的创建和编辑视图中的下拉列表
@Html.DropDownList("ReportsTo", ViewBag.Users as SelectList, "Choose User", htmlAttributes: new { @class = "form-control" })
我需要获取下拉列表以在编辑视图中检索当前保存的值,并在索引和详细信息视图中显示GUID作为用户的名和姓。如果有人有替代解决方案,而不是尝试使用当前方法来完成它,我也很乐意尝试。
预先感谢:)
答案 0 :(得分:0)
我设法解决了这个问题。它可能不是绝对最佳的解决方案,但似乎可行。这是下面的解决方案。我已将上面代码中的ReportsTo替换为解决方案中的SuperiorID。请注意,我的“身份用户”的ID带有整数,而不像默认的Identity实现那样带有GUID。
使用以下代码,我已将一个身份用户链接到另一个身份用户。
在我的身份模型中,我的ApplicationUser中有以下内容:Identity User类:
public class ApplicationUser : IdentityUser<int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserClaim>, IUser<int>
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int? SuperiorID { get; set; }
public string FullName
{
get
{
return FirstName + " " + LastName;
}
}
public async Task<ClaimsIdentity>
GenerateUserIdentityAsync(UserManager<ApplicationUser, int> manager)
{
var userIdentity = await manager
.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
return userIdentity;
}
public virtual ApplicationUser Superior { get; set; }
}
我为上级创建了一个摘要,该摘要继承了身份用户,以便获得用户的ID和全名,这些ID和全名也放在了身份模型中:
public abstract class Superior : IdentityUser
{
}
我在RegisterViewModel中添加了以下内容,以便在用户创建时添加上级:
public class RegisterViewModel
{
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
public string FullName
{
get
{
return FirstName + " " + LastName;
}
}
[Display(Name = "Superior")]
public virtual ApplicationUser Superior { get; set; }
}
我在EditUserViewModel中添加了以下内容,以便可以在编辑视图中编辑用户的上级:
public class EditUserViewModel
{
public int Id { get; set; }
[Display(Name = "First Name")]
public string FirstName { get; set; }
[Display(Name = "Last Name")]
public string LastName { get; set; }
public string FullName
{
get
{
return FirstName + " " + LastName;
}
}
[Display(Name = "Superior")]
public int? SuperiorID { get; set; }
public virtual ApplicationUser Superior { get; set; }
}
这是UserController的代码。我删除了与此无关的代码,并留下了一些代码来指示代码需要去的地方:
这出现在主类中:
private ApplicationDbContext db = new ApplicationDbContext();
public async Task<ActionResult> Index(int? SelectedSuperior)
{
var superiors = db.Users.OrderBy(s => s.FirstName).ToList();
ViewBag.SelectedSuperior = new SelectList(superiors, "Id", "FullName", SelectedSuperior);
int superiorID = SelectedSuperior.GetValueOrDefault();
IQueryable<ApplicationUser> users = db.Users
.Where(c => !SelectedSuperior.HasValue || c.SuperiorID == superiorID)
.OrderBy(d => d.Id)
.Include(d => d.Superior);
var sql = users.ToString();
return View(await UserManager.Users.ToListAsync());
}
public ActionResult Create()
{
PopulateSuperiorsDropDownList();
return View();
}
public async Task<ActionResult> Create(RegisterViewModel userViewModel)
{
if (ModelState.IsValid)
{
var user = new ApplicationUser
{
FirstName = userViewModel.FirstName,
LastName = userViewModel.LastName,
SuperiorID = userViewModel.SuperiorID,
};
}
PopulateSuperiorsDropDownList(userViewModel.SuperiorID);
return View();
}
public async Task<ActionResult> Edit(int id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var user = await UserManager.FindByIdAsync(id);
if (user == null)
{
return HttpNotFound();
}
var model = new EditUserViewModel()
{
Id = user.Id,
FirstName = user.FirstName,
LastName = user.LastName,
SuperiorID = user.SuperiorID,
};
PopulateSuperiorsDropDownList(user.SuperiorID);
return View(model);
}
public async Task<ActionResult> Edit([Bind(Include = "Email,Id,FirstName,LastName,SuperiorID")] EditUserViewModel editUser)
{
if (ModelState.IsValid)
{
var user = await UserManager.FindByIdAsync(editUser.Id);
if (user == null)
{
return HttpNotFound();
}
// Update the User:
user.Email = editUser.Email;
user.FirstName = editUser.FirstName;
user.LastName = editUser.LastName;
user.SuperiorID = editUser.SuperiorID;
}
ModelState.AddModelError("", "Something failed.");
PopulateSuperiorsDropDownList(editUser.SuperiorID);
return View();
}
private void PopulateSuperiorsDropDownList(object selectedSuperior = null)
{
var superiorsQuery = from s in db.Users
orderby s.FirstName + " " + s.LastName
select s;
ViewBag.SuperiorID = new SelectList(superiorsQuery, "Id", "FullName", selectedSuperior);
}
以下是创建和编辑视图的下拉列表,以便可以将上级分配给用户:
@Html.DropDownList("SuperiorID", null, "Choose Superior", htmlAttributes: new { @class = "form-control" })
要在详细信息页面中显示用户上级的全名,我使用以下代码:
@Html.TextBoxFor(m => m.Superior.FullName, new { @class = "form-control", @disabled = "disabled" })
要在索引页的数据表中显示用户上级的全名,我使用了以下方法:
<table class="table" id="users-table" width="100%">
<thead>
<tr>
<th title="First Name">
First Name
</th>
<th title="Last Name">
Last Name
</th>
<th title="Superior">
Superior
</th>
</tr>
</thead>
<tbody>
@foreach (var item in Model)
{
<tr>
<td>
@Html.DisplayFor(modelItem => item.FirstName)
</td>
<td>
@Html.DisplayFor(modelItem => item.LastName)
</td>
<td>
@Html.DisplayFor(modelItem => item.Superior.FullName)
</td>
</tr>
}
</tbody>
</table>