tutorial tables net mvc framework asp and asp.net-mvc asp.net-mvc-5 asp.net-identity

asp.net-mvc - tables - authorize roles mvc 5



ASP.NET MVC 5 cómo eliminar un usuario y sus datos relacionados en Identity 2.0 (3)

Actualización para ASP.NET Core 2.0: espero que esto ahorre un poco de tiempo a alguien

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

Hola, estoy siguiendo este artículo para eliminar un usuario en Identity 2.0 http://www.asp.net/mvc/tutorials/mvc-5/introduction/examining-the-details-and-delete-methods

Sin embargo, primero debo eliminar todos los registros relacionados en AspNetUserRoles y luego eliminar al usuario.

Encontré un ejemplo escrito en Identity 1.0 y algunos de los métodos utilizados en este ejemplo no existen.

// 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(); } }

No puedo encontrar IdentityManager desde cualquier lugar, y context.Users tampoco tiene el método FindAsync() .

Ayude a descubrir cómo eliminar correctamente un usuario y sus registros relacionados en Identity 2.0

Gracias.


Creo que las clases que estás buscando son UserManager y RoleManager . En mi opinión, son la mejor manera de ir en contra del contexto directamente.

El UserManager define un método RemoveFromRoleAsync que le brinda la capacidad de eliminar al usuario (identificado por su clave) de un rol determinado. También define varios métodos de búsqueda, como FindAsync , FindByIdAsync , FindByNameAsync o FindByEmailAsync . Todos ellos pueden ser utilizados para recuperar un usuario. Para eliminar un usuario, debe usar el método DeleteAsync que acepta un objeto de usuario como parámetro. Para obtener los roles, un usuario es miembro de Identity y le da el método GetRolesAsync donde pasa el ID del usuario. También veo que está intentando eliminar un inicio de sesión de un usuario. Para este propósito debes usar el método RemoveLoginAsync .

En general, su código sería similar al siguiente:

// 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(); } }

Deberá ajustar este fragmento a sus necesidades, porque no tengo una idea de cómo se ve su implementación de IdentityUser . Recuerde declarar el UserManager según sea necesario. Puede encontrar un ejemplo de cómo podría hacer esto cuando cree un nuevo proyecto en Visual Studio utilizando Cuentas individuales .


  • El punto de Brad sobre la necesidad de requerir @ Html.AntiForgeryToken () en las vistas no es necesario si está utilizando las últimas versiones de ASP.NET. Consulte AntiForgeryToken.
  • ¿Por qué no crear un desencadenador SQL para AspNetUsers para eliminar un usuario que también elimina los registros correspondientes para el usuario de AspNetUserRoles y AspNetUserLogins?
  • Necesito invocar DeleteUser desde varios lugares, así que agregué un método estático a AccountController (ver más abajo). Todavía estoy aprendiendo sobre MVC, por lo que debería agradecer los comentarios, en particular 1) el uso de IdentityResult como un código de retorno 2) la sabiduría de extender AccountController de esta manera 3) el enfoque para poner una contraseña (texto claro) en el Modelo para validar el acción (ver ejemplo de invocación).

    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; }

Ejemplo de invocación: el formulario pasa la contraseña del usuario (texto claro) en el Modelo:

// 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); }