Как связать пользователя с другим пользователем в ASP.NET MVC 5 и Identity (Entity Framework Code-First) - PullRequest
0 голосов
/ 24 декабря 2018

Мне нужна помощь, чтобы связать пользователя с другим пользователем в ASP.NET MVC 5 и ASP.NET Identity в подходе Entity Framework Code-First.

Случай использования здесь, когда я создаю пользователя, мне нужновыберите пользователя в раскрывающемся списке ReportsTo, который отображает имя и фамилию пользователя и сохраняет идентификатор выбранного пользователя в столбце my ReportsTo в таблице Identity User.Этот список пользователей должен быть списком существующих пользователей Identity в базе данных.

Я реализовал биты различных тем и сумел получить раскрывающийся список для отображения вместе с пользователями Identity в моем пользователе.редактировать представления.Он сохраняет идентификатор в моем столбце ReportsTo в базе данных, но когда я редактирую пользователя, поле ReportsTo не сохраняет идентификатор, сохраненный в базе данных, если я снова не сделаю тот же выбор в раскрывающемся списке (он перезаписывает ранее сохраненное значение с помощьюпусто, если я не делаю выбор снова, поскольку он не загружает ранее сохраненное значение в представлении редактирования), а на странице сведений и в моей таблице списка пользователей отображается сохраненный пользователь 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 в моем представлении индекса и сведений в качестве имени и фамилии пользователя.Если у кого-то есть альтернативное решение вместо того, чтобы пытаться выполнить его с помощью текущего метода, я был бы рад попробовать это тоже.

Заранее спасибо:)

1 Ответ

0 голосов
/ 02 января 2019

Мне удалось обойти проблему.Возможно, это не самое лучшее решение, но оно работает.Вот решение ниже.Я заменил ReportsTo из приведенного выше кода на SuperiorID в решении.Обратите внимание, что у моих пользователей Identity есть целые числа для их идентификаторов, а не GUID, как у реализации Identity по умолчанию.

С помощью приведенного ниже кода я связал пользователя Identity с другим пользователем Identity.

В моих моделях идентификацииУ меня в 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; }

    } 

Я создал реферат для начальства, который наследует Identity User, чтобы я мог получить идентификатор и полное имя пользователя, которые я также поместил в свой идентификатор.Модели:

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> 
...