ASP.NET MVC 5如何在Identity 2.0中删除用户及其相关数据



我将按照本文删除Identity 2.0中的一个用户http://www.asp.net/mvc/tutorials/mvc-5/introduction/examining-the-details-and-delete-methods

但是,我需要先删除AspNetUserRoles中的所有相关记录,然后再删除用户。

我发现了一个用Identity 1.0编写的例子,其中使用的一些方法不存在。

   // POST: /Users/Delete/5
        [HttpPost, ActionName("Delete")]
        [ValidateAntiForgeryToken]
        public async Task<ActionResult> DeleteConfirmed(string id)
        {
            if (ModelState.IsValid)
            {
                if (id == null)
                {
                    return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
                }
                var user = await context.Users.FindAsync(id);
                var logins = user.Logins;
                foreach (var login in logins)
                {
                    context.UserLogins.Remove(login);
                }
                var rolesForUser = await IdentityManager.Roles.GetRolesForUserAsync(id, CancellationToken.None);
                if (rolesForUser.Count() > 0)
                {
                    foreach (var item in rolesForUser)
                    {
                        var result = await IdentityManager.Roles.RemoveUserFromRoleAsync(user.Id, item.Id, CancellationToken.None);
                    }
                }
                context.Users.Remove(user);
                await context.SaveChangesAsync();
                return RedirectToAction("Index");
            }
            else
            {
                return View();
            }
        }

我找不到IdentityManager, context.Users也没有FindAsync()方法。

如何在Identity 2.0中正确删除User及其相关记录?

我认为你正在寻找的类是UserManager和RoleManager。在我看来,比起直接违背上下文,它们是更好的方法。

UserManager定义了一个方法RemoveFromRoleAsync,它使您能够从给定的角色中删除用户(由其密钥标识)。它还定义了几个Find方法,如FindAsync、FindByIdAsync、FindByNameAsync或FindByEmailAsync。它们都可以用来检索用户。要删除一个用户,你应该使用DeleteAsync方法,该方法接受一个用户对象作为参数。要获取用户作为Identity成员的角色,您可以使用GetRolesAsync方法,在该方法中传入用户的ID。此外,我看到你试图从用户删除登录。为此,您应该使用RemoveLoginAsync方法。

总之,你的代码看起来就像下面这个:

// POST: /Users/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> DeleteConfirmed(string id)
{
  if (ModelState.IsValid)
  {
    if (id == null)
    {
      return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
    }
    var user = await _userManager.FindByIdAsync(id);
    var logins = user.Logins;
    var rolesForUser = await _userManager.GetRolesAsync(id);
    using (var transaction = context.Database.BeginTransaction())
    {
      foreach (var login in logins.ToList())
      {
        await _userManager.RemoveLoginAsync(login.UserId, new UserLoginInfo(login.LoginProvider, login.ProviderKey));
      }
      if (rolesForUser.Count() > 0)
      {
        foreach (var item in rolesForUser.ToList())
        {
          // item should be the name of the role
          var result = await _userManager.RemoveFromRoleAsync(user.Id, item);
        }
      }
      await _userManager.DeleteAsync(user);
      transaction.Commit();
    }
    return RedirectToAction("Index");
  }
  else
  {
    return View();
  }
}

您需要根据您的需要调整这个代码片段,因为我不知道您的IdentityUser实现是什么样的。记住根据需要声明UserManager。当您在Visual Studio中使用Individual Accounts创建一个新项目时,可以找到一个如何做到这一点的示例。

更新为ASP。. NET Core 2.0 -希望这能节省一些时间

ApplicationDbContext context, 
UserManager<ApplicationUser> userManager, 
ApplicationUser user
var logins = await userManager.GetLoginsAsync(user);
var rolesForUser = await userManager.GetRolesAsync(user);
using (var transaction = context.Database.BeginTransaction())
{
    IdentityResult result = IdentityResult.Success;
    foreach (var login in logins)
    {
        result = await userManager.RemoveLoginAsync(user, login.LoginProvider, login.ProviderKey);
        if (result != IdentityResult.Success)
            break;
    }
    if (result == IdentityResult.Success)
    {
        foreach (var item in rolesForUser)
        {
            result = await userManager.RemoveFromRoleAsync(user, item);
            if (result != IdentityResult.Success)
                break;
        }
    }
    if (result == IdentityResult.Success)
    {
        result = await userManager.DeleteAsync(user);
        if (result == IdentityResult.Success)
            transaction.Commit(); //only commit if user and all his logins/roles have been deleted  
    }
}
    如果你使用的是最新版本的ASP, Brad关于在视图中要求@Html.AntiForgeryToken()的观点是没有必要的。. NET -参见AntiForgeryToken仍然需要
  • 为什么不为AspNetUsers创建一个SQL触发器,这样删除一个用户也会从AspNetUserRoles和AspNetUserLogins中删除相应的用户记录?
  • 我需要从许多地方调用DeleteUser,所以我添加了一个静态方法到AccountController(见下文)。我仍然在学习MVC,所以应该感谢您的评论,特别是1)使用IdentityResult作为返回代码2)以这种方式扩展AccountController的智慧3)将密码(明文)放入模型以验证操作的方法(参见示例调用)。

     public static async Task<IdentityResult> DeleteUserAccount(UserManager<ApplicationUser> userManager, 
                                                                             string userEmail, ApplicationDbContext context)
    {
         IdentityResult rc = new IdentityResult();
        if ((userManager != null) && (userEmail != null) && (context != null) )
        {
            var user = await userManager.FindByEmailAsync(userEmail);
            var logins = user.Logins;
            var rolesForUser = await userManager.GetRolesAsync(user);
            using (var transaction = context.Database.BeginTransaction())
            {
              foreach (var login in logins.ToList())
              {
                await userManager.RemoveLoginAsync(user, login.LoginProvider, login.ProviderKey);
              }
              if (rolesForUser.Count() > 0)
              {
                foreach (var item in rolesForUser.ToList())
                {
                  // item should be the name of the role
                  var result = await userManager.RemoveFromRoleAsync(user, item);
                }
              }
              rc = await userManager.DeleteAsync(user);
              transaction.Commit();
            }
        }
        return rc;
    }
    

示例调用-表单在Model:

中传递用户的密码(明文)
        // POST: /Manage/DeleteUser
    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> DeleteUser(DeleteUserViewModel account)
    {
        var user = await GetCurrentUserAsync();
        if ((user != null) && (user.PasswordHash != null) && (account != null) && (account.Password != null))
        {
            var hasher = new Microsoft.AspNetCore.Identity.PasswordHasher<ApplicationUser>();
            if(hasher.VerifyHashedPassword(user,user.PasswordHash, account.Password)  != PasswordVerificationResult.Failed)
            {
                IdentityResult rc = await AccountController.DeleteUserAccount( _userManager, user.Email, _Dbcontext); 
                if (rc.Succeeded)
                {
                    await _signInManager.SignOutAsync();
                    _logger.LogInformation(4, "User logged out.");
                    return RedirectToAction(nameof(HomeController.Index), "Home");
                }
            }
        }
        return View(account);
    }

我也在寻找答案,但最后这是什么对我来说很好,即使是旧的帖子,但它可能对某人有帮助。

// GET: Users/Delete/5
    public ActionResult Delete(string id)
    {
        using (SqlConnection sqlCon = new SqlConnection(connectionString))
        {
            sqlCon.Open();
            string query = "DELETE FROM AspNetUsers WHERE Id = @Id";
            SqlCommand sqlCmd = new SqlCommand(query, sqlCon);
            sqlCmd.Parameters.AddWithValue("@Id", id);
            sqlCmd.ExecuteNonQuery();
        }
        return RedirectToAction("Index");
    }
    // POST: Users/Delete/5
    [HttpPost]
    public ActionResult Delete(string id, FormCollection collection)
    {
        try
        {
            // TODO: Add delete logic here
            return RedirectToAction("Index");
        }
        catch
        {
            return View();
        }
    }

相关内容

  • 没有找到相关文章

最新更新