3

Using .net 5 and identity, I cannot figure out how to set AutoSaveChanges on my startup file. If something fails during register or login code, i need to do a lot of cleanup on my user tables.

services.AddDefaultIdentity<MyUser()
.AddRoles<IdentityRole().AddEntityFrameworkStores<MyDbContext>();

I see an answer in Prevent ASP.NET Identity's UserManager from automatically saving, but do not know how this relates to my startup service.

Tatranskymedved
  • 4,194
  • 3
  • 21
  • 47
a2ron44
  • 1,711
  • 1
  • 13
  • 18

1 Answers1

0

Found an older post that still works for .NET 5.

To turn off AutoSave in UserManager, you need to register a custom UserStore. To do this, create a new file:

public class CustomUserStore : UserStore<IdentityUser>  // important to use custom Identity user object here!  
    {
        public CustomUserStore(AppDbContext context)
        : base(context)
        {
            AutoSaveChanges = false;
        }
    }

In Startup.cs, add the dependency injection by adding the following to ConfigureServices:

services.AddScoped<IUserStore<IdentityUser>, CustomUserStore>();
Make sure to use the same Identity Object or it will not work!

Now, when you do this, UserManager still does not fully work without saving the user to the database before adding claims or roles. You have to implement your own rollback of data if things fail. For instance, my AuthController has logic to try and add a role. If that fails, I will remove to user just created:

                var isCreated = await _userManager.CreateAsync(newUser, user.Password);
                await _context.SaveChangesAsync();  

                if (!isCreated.Succeeded)
                {
                    var roleResult = await _userManager.AddToRoleAsync(newUser, "User");

                    if (!roleResult.Succeeded)
                    {
                        throw new Exception("not saved");

                    }
                    await _context.SaveChangesAsync();
                    var jwtToken = await GenerateAuthResult(newUser, null);
                        
                    return Ok(jwtToken);  // or whatever response needed
                }
                else
                {
                    await _userManager.DeleteAsync(newUser);
                    await _context.SaveChangesAsync()
                    return BadRequest( // add response );
                }

Old post: UserManager's AutoSaveChanges in .NET Core 2.1

Issue posted on Identity not being fully transactional: https://github.com/dotnet/aspnetcore/issues/18407

a2ron44
  • 1,711
  • 1
  • 13
  • 18