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

Asp.net mvc ASP.NET MVC 5如何在Identity 2.0中删除用户及其相关数据,asp.net-mvc,asp.net-mvc-5,asp.net-identity,Asp.net Mvc,Asp.net Mvc 5,Asp.net Identity,我跟随这篇文章删除Identity 2.0中的一个用户 但是,我需要先删除AspNetUserRoles中的所有相关记录,然后删除该用户 我发现了一个用Identity 1.0编写的示例,该示例中使用的一些方法不存在 // POST: /Users/Delete/5 [HttpPost, ActionName("Delete")] [ValidateAntiForgeryToken] public async Task&

我跟随这篇文章删除Identity 2.0中的一个用户

但是,我需要先删除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();
            }
        }
//POST:/Users/Delete/5
[HttpPost,ActionName(“删除”)]
[ValidateAntiForgeryToken]
公共异步任务已确认(字符串id)
{
if(ModelState.IsValid)
{
if(id==null)
{
返回新的HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var user=wait context.Users.FindAsync(id);
var logins=user.logins;
foreach(登录中的var登录)
{
context.UserLogins.Remove(login);
}
var rolesForUser=await IdentityManager.Roles.GetRolesForUserAsync(id,CancellationToken.None);
if(rolesForUser.Count()>0)
{
foreach(rolesForUser中的var项)
{
var result=await IdentityManager.Roles.RemoveUserFromRoleAsync(user.Id、item.Id、CancellationToken.None);
}
}
context.Users.Remove(用户);
wait context.saveChangesSync();
返回操作(“索引”);
}
其他的
{
返回视图();
}
}
我在任何地方都找不到
IdentityManager
,也找不到
context。用户
也没有
FindAsync()
方法


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

我认为您要查找的类是和。在我看来,他们是更好的方式,而不是直接违背上下文

UserManager定义了一种方法,使您能够从给定角色中删除该用户(由其密钥标识)。它还定义了几种查找方法,如、或。它们都可以用于检索用户。要删除用户,应使用接受用户对象作为参数的方法。要获取用户是Identity成员的角色,您可以使用传递用户ID的方法。我还看到您试图从用户中删除登录名。为此,您应该使用该方法

总之,您的代码看起来与以下代码类似:

// 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();
  }
}
//POST:/Users/Delete/5
[HttpPost,ActionName(“删除”)]
[ValidateAntiForgeryToken]
公共异步任务已确认(字符串id)
{
if(ModelState.IsValid)
{
if(id==null)
{
返回新的HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
var user=await\u userManager.FindByIdAsync(id);
var logins=user.logins;
var rolesForUser=wait_userManager.GetRolesAsync(id);
使用(var transaction=context.Database.BeginTransaction())
{
foreach(logins.ToList()中的var登录)
{
wait_userManager.removeloginanc(login.UserId,new UserLoginInfo(login.LoginProvider,login.ProviderKey));
}
if(rolesForUser.Count()>0)
{
foreach(rolesForUser.ToList()中的变量项)
{
//项应该是角色的名称
var result=wait_userManager.RemoveFromRoleAsync(user.Id,item);
}
}
wait_userManager.deleteAync(用户);
Commit();
}
返回操作(“索引”);
}
其他的
{
返回视图();
}
}
您需要根据需要调整此代码段,因为我不知道您的IdentityUser实现是什么样子的。记住根据需要声明用户管理器。当您在Visual Studio中使用个人帐户创建新项目时,可以找到一个示例,说明如何做到这一点
  • 如果您使用的是最新版本的ASP.NET,Brad关于在视图中要求@Html.AntiForgeryToken()的观点是不必要的-请参阅
  • 为什么不为AspNetUsers创建一个SQL触发器,这样删除一个用户也会从AspNetUserRoles和AspNetUserLogins中删除用户的相应记录
  • 我需要从许多地方调用DeleteUser,因此我向AccountController添加了一个静态方法(见下文)。我仍在学习MVC,因此我应该感谢大家的评论,特别是1)使用IdentityResult作为返回代码2)以这种方式扩展AccountController的智慧3)将密码(明文)放入模型以验证操作的方法(请参见示例调用)

    公共静态异步任务DeleteUserAccount(UserManager用户管理器,
    字符串userEmail,ApplicationDbContext上下文)
    {
    IdentityResult rc=新IdentityResult();
    if((userManager!=null)&&&(userEmail!=null)&&&(context!=null))
    {
    var user=await userManager.findbyemailsync(userEmail);
    var logins=user.logins;
    var rolesForUser=await userManager.GetRolesAsync(用户);
    使用(var transaction=context.Database.BeginTransaction())
    {
    foreach(logins.ToList()中的var登录)
    {
    等待userManager.removeloginanc(用户,login.LoginProvider,login.ProviderKey);
    }
    if(rolesForUser.Count()>0)
    {
    foreach(rolesForUser.ToList()中的变量项)
    {
    //项应该是角色的名称
    var result=await userManager.RemoveFromRoleAsync(用户,项);
    }
    }
    rc=等待userManager.DeleteAsync(用户);
    Commit();
    }
    }
    返回rc;
    }
    
  • 示例调用-表单传递用户的密码
     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;
    }
    
            // 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);
        }
    
    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  
        }
    }
    
    // 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();
            }
        }