Search code examples
c#asp.net-coreasp.net-core-mvcentity-framework-coreasp.net-core-2.2

Can't update SQL Bit column with ASP .NET Core


I have an ASP .NET Core web app, and when I created the project the authentication was set up automatically using the individual user accounts option. The database tables for user accounts/roles were also created automatically.

I created my own ApplicationUser class which inherits from IdentityUser, and I added parameters for FirstName, LastName and LockoutReason. (I added these fields to the DB table as well) Now I'm trying to add a feature to allow someone to manually lock out a user, and I can't seem to update the LockoutEnabled field in the database. Every time I do, it automatically gets reset to false.

Here is a picture of the form: enter image description here

And the GET/POST code for it:

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

When I click the Lock button, the LockoutEnd and LockoutReason fields are updated correctly, but the LockoutEnabled field remains false and the account isn't locked out.

New POST method after trying to implement solution:

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

Solution

  • You need the combination of the two proprieties The LockoutEnabled and LockoutEnd.

    The LockoutEnabled is an indicator to see if the user could be locked out or not, and the LockoutEnd is a DateTimeOffset. So in order to lock the user set the lockout to true and put the value of LockoutEnd in the future, because A value in the past means the user is not locked out.