I am using AspNet.Identity for User Management in my MVC project because I believe it is a great start, now that I have it working (with little changes), I wanted to add an Audit Trail (Track Changes) like my other DbContext that I use.
In IdentityModel.cs, I have the following code that works, but only in certain situations:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
//Can't recall if this was there by default
Configuration.AutoDetectChangesEnabled = true;
}
public override int SaveChanges()
{
//Tell EF to Track Changes
ChangeTracker.DetectChanges();
//More code once I get this working
//
}
}
In my Controller, I have the following:
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(EditUserViewModel editUser)
{
var user = await UserManager.FindByIdAsync(editUser.Id);
//Update a property within the User object
user.FirstName = "Updated First Name";
//Save to database
var result = UserManager.Update(user);
//The above saves to database, but doesn't trigger SaveChanges()
//SaveChanges() will be triggered if I call
HttpContext.GetOwinContext().Get<ApplicationDbContext>().SaveChanges();
}
When the above HttpContext.GetOwinContext().Get<ApplicationDbContext>().SaveChanges(); is called, the updated ApplicationUser has an EntityState of Unchanged. Makes sense as it was already saved.
However, I am trying to see how I can utilize the UserManager and still work with SaveChanges().
I also understand that I could write a class that would log all of this myself, but as I expand the ApplicationUser (or ApplicationRole) I would like to avoid the extra coding for the Audit Log.
Any advice or links would help!
Set AutoSaveChanges to false in the constructor of your UserStore (which you would pass to the constructor of the UserManager).
public class MyUserStore : UserStore<User, Role, int, UserLogin, UserRole, UserClaim>
{
private MyDbContext _context;
public MyUserStore(MyDbContext context) : base(context)
{
//Set this to false
AutoSaveChanges = false;
_context = context;
}
}
Now you can call save changes as you normally would and the change tracker will contain the changes you're expecting.
I did however encounter an OptimisticConcurrencyException when I tried to make more than one call to UserManager between calls to SaveChanges. I just called SaveChanges after each UserManager operation.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With