こんにちは、私はこの記事に従って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でユーザーとその関連レコードを適切に削除する方法を理解するのを手伝ってください
ありがとう。
探しているクラスは serManager と RoleManager であると思います。私の意見では、それらはコンテキストに直接反するのではなく、より良い方法です。
UserManagerはメソッドを定義します RemoveFromRoleAsync 指定されたロールからユーザー(キーで識別)を削除する機能を提供します。また、 FindAsync 、 FindByIdAsync 、 FindByNameAsync 、または FindByEmailAsync などのいくつかのFindメソッドも定義しています。これらはすべて、ユーザーを取得するために使用できます。ユーザーを削除するには、ユーザーオブジェクトをパラメーターとして受け入れる DeleteAsync メソッドを使用する必要があります。ユーザーがIdentityのメンバーであるロールを取得するには、ユーザーのIDを渡す GetRolesAsync メソッドを提供します。また、ユーザーからログインを削除しようとしていることがわかります。このためには、 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で新しいプロジェクトを作成するときに見つけることができます。
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
}
}
いくつかの場所から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;
}
サンプル呼び出し-フォームは、モデルでユーザーのパスワード(クリアテキスト)を渡します。
// 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();
}
}