Ho un'applicazione web ASP .NET Core e, quando ho creato il progetto, l'autenticazione è stata impostata automaticamente utilizzando l'opzione degli account utente individuali. Anche le tabelle del database per account / ruoli utente sono state create automaticamente.
Ho creato la mia classe ApplicationUser che eredita da IdentityUser e ho aggiunto i parametri per FirstName, LastName e LockoutReason. (Ho aggiunto anche questi campi alla tabella DB) Ora sto cercando di aggiungere una funzionalità per consentire a qualcuno di bloccare manualmente un utente e non riesco a aggiornare il campo LockoutEnabled nel database. Ogni volta che lo faccio, viene automaticamente ripristinato su false.
E il codice GET / POST per questo:
//GET Users lock
public async Task<IActionResult> Lock(string id)
{
if (id == null)
{
return NotFound();
}
var userFromDb = await _db.ApplicationUser.SingleOrDefaultAsync(m => m.Id == id);
if (userFromDb == null)
{
return NotFound();
}
else
{
return View(userFromDb);
}
}
//POST Users lock
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Lock(string Id, ApplicationUser model)
{
var userFromDb = await _db.Users.Where(u => u.Id == Id).FirstOrDefaultAsync();
userFromDb.LockoutEnd = model.LockoutEnd;
userFromDb.LockoutEnabled = true;
userFromDb.AccessFailedCount = model.AccessFailedCount;
userFromDb.LockoutReason = model.LockoutReason;
_db.ApplicationUser.Update(userFromDb);
await _db.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
ApplicationUser.cs
public class ApplicationUser : IdentityUser
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string LockoutReason { get; set; }
}
Quando faccio clic sul pulsante Blocca, i campi LockoutEnd e LockoutReason vengono aggiornati correttamente, ma il campo LockoutEnabled rimane falso e l'account non viene bloccato.
Nuovo metodo POST dopo aver tentato di implementare una soluzione:
//POST Users lock
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Lock(string Id, ApplicationUser model)
{
var userFromDb = await _db.Users.Where(u => u.Id == Id).FirstOrDefaultAsync();
userFromDb.LockoutEnd = model.LockoutEnd;
userFromDb.AccessFailedCount = model.AccessFailedCount;
userFromDb.LockoutReason = model.LockoutReason;
_db.ApplicationUser.Update(userFromDb);
await _db.SaveChangesAsync();
var user2 = await _userManager.FindByIdAsync(userFromDb.Id);
var result = await _userManager.SetLockoutEnabledAsync(user2, true);
return RedirectToAction(nameof(Index));
}
È necessaria la combinazione delle due proprietà The LockoutEnabled
e LockoutEnd
.
Il LockoutEnabled
è un indicatore per vedere se l'utente può essere bloccato o meno, e il LockoutEnd
è un DateTimeOffset. Quindi, per bloccare l'utente, impostare il blocco su true e inserire il valore di LockoutEnd
in futuro, perché un valore nel passato indica che l'utente non è bloccato.
UserManager<ApplicationUser> _userManager
_userManager = userManager; //DI'd via CTOR for the class
non viene mai eseguito con accesso diretto con la tabella dalla tabella utente.
nel tuo caso potresti aver bisogno di afferrare l'utente con una chiamata a var user = await _userManager.FindByIdAsync(model.Id)
perché potresti non avere abbastanza informazioni con il passaggio dal post popolato all'interno della variabile del modello.
//used from with in method
//model.LockoutEnabled will be either true or false depending on your selection
//from the view.
var result = await _userManager.SetLockoutEnabledAsync(user, model.LockoutEnabled);
questo restituisce IdentityResult
che ha la proprietà Errors collection o bool Succeeded, può essere gestito a piacere.