ASP.NET ОСНОВНОЕ добавление и удаление ролей

#model-view-controller #asp.net-core-mvc #asp.net-core-identity

#model-view-controller #asp.net-core-mvc #asp.net-core-identity

Вопрос:

Как следует из названия, я пытаюсь добавить роли из массива, который я получаю, если роли не соответствуют тем, которые есть у пользователя. Те, которые соответствуют, я хочу удалить. вот моя логика контроллера. идентификатор строки — это имя роли, которую я получаю. Также, когда я запускаю этот код, я получаю исключение со словами «Отметка безопасности пользователя не может быть нулевой.«

 [HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, User user, string[] roles)
{
    if (id != user.Id)
    {
        return NotFound();
    }

    if (ModelState.IsValid)
    {
        try
        {
            var listOfRoles = await privateUser.GetRolesAsync(user);

            foreach (var role in listOfRoles.Except(roles))
            {
                await privateUser.RemoveFromRoleAsync(user, role);
            }

            foreach(var role in roles.Except(listOfRoles))
            {
                await privateUser.AddToRoleAsync(user, role);
            }

            await _context.SaveChangesAsync();
        }
        catch (DbUpdateConcurrencyException)
        {
            if (!UserExists(user.Id))
            {
                return NotFound();
            }
            else
            {
                throw;
            }
        }
        return RedirectToAction(nameof(Index));
    }
    return View(user);
}
  

Ответ №1:

Вы используете пользователя, полученного через POST, что не только является плохой практикой, но даже не будет работать здесь, потому что вы не публикуете полный User объект. А именно, значение SecurityStamp отсутствует, о чем и сообщает вам исключение.

Не публикуйте User . Вместо этого используйте идентификатор пользователя для извлечения его из базы данных:

 [HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, string[] roles)
{
    var user = await _userManager.FindByIdAsync(id);
    if (user == null)
    {
        return NotFound();
    }

    // the rest of your code
  

ОБНОВЛЕНИЕ (для одновременного изменения пользователя)

 [HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Edit(string id, User model, string[] roles)
{
    var user = await _userManager.FindByIdAsync(id);
    if (user == null)
    {
        return NotFound();
    }

    // map over the values from `model` (i.e. the posted `User`)
    user.FirstName = model.FirstName;
    // etc.

    // use `user` not `model` for role management functions
  

Комментарии:

1. Это каркас для редактирования пользователя. это было там, вот почему это было так. Я воспользуюсь вашим советом.

2. Если это представление для редактирования пользователем, вам все равно может понадобиться User параметр (хотя на самом деле вместо него следует использовать view model). Однако экземпляр пользователя для вашей роли, добавляющий материал, должен быть пользователем из базы данных, по-прежнему, а не тем, что было опубликовано.

3. Спасибо, это помогло мне!