【问题标题】:How can I link a user to another user in ASP.NET MVC 5 and Identity (Entity Framework Code-First)如何在 ASP.NET MVC 5 和身份(实体框架代码优先)中将用户链接到另一个用户
【发布时间】:2019-01-03 03:18:12
【问题描述】:

我需要帮助在 ASP.NET MVC 5 中将用户链接到另一个用户,并在 Entity Framework Code-First 方法中使用 ASP.NET Identity。

这里的用例是当我创建用户时,我需要在 ReportsTo 下拉列表中选择一个用户,该下拉列表显示用户的名字和姓氏,并将所选用户的 ID 保存在 Identity User 表的 ReportsTo 列中。此用户列表需要是数据库中现有 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 显示为用户的名字和姓氏。如果有人有替代解决方案而不是尝试使用当前方法完成它,我也很乐意尝试。

提前致谢:)

【问题讨论】:

  • 目前还不清楚,您的问题或问题是什么。您的保存方法是否无法正常工作或您的下拉列表?
  • 嗨,马可。如上所述,我的代码有两个问题。在编辑中,它不会检索保存的值,并在详细信息和索引中显示一个 GUID,而不是保存的 ID 的名字和姓氏
  • 那么你必须提供这两种情况的代码。
  • 嗨,马可。我已经更新了我的帖子,并包含了我的控制器中的创建和编辑方法。我还添加了 EditUserViewModel 的代码
  • ReportsTo 的类型应该是ApplicationUser 而不是string,所以Entity Framework 可以正确设置外键

标签: c# asp.net-mvc-5 asp.net-identity


【解决方案1】:

我已经设法解决了这个问题。它可能不是绝对的最佳解决方案,但它似乎有效。这是下面的解决方案。我已将上述代码中的 ReportsTo 替换为解决方案中的 SuperiorID。请注意,我的身份用户的 ID 是整数,而不是像默认身份实现那样的 GUID。

通过下面的代码,我将一个身份用户链接到另一个身份用户。

在我的身份模型中,我的 ApplicationUser 中有以下内容:身份用户类:

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 和全名:

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> 

【讨论】:

    猜你喜欢
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-05
    • 1970-01-01
    • 2021-04-22
    • 2011-12-17
    相关资源
    最近更新 更多