[asp.net-mvc] Updating user data - ASP.NET Identity

I've added custom fields to the ApplicationUser class
I've also created a form through which the user can enter/edit the fields.
However for some reason I'm not able to update the fields in the database.

[HttpPost]
[ActionName("Edit")]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Manage(EditProfileViewModel model)
{
    if (ModelState.IsValid)
    {
        // Get the current application user
        var user = User.Identity.GetApplicationUser();

        // Update the details
        user.Name = new Name { First = model.FirstName, Last = model.LastName, Nickname = model.NickName };
        user.Birthday = model.Birthdate;

        // This is the part that doesn't work
        var result = await UserManager.UpdateAsync(user);

        // However, it always succeeds inspite of not updating the database
        if (!result.Succeeded)
        {
            AddErrors(result);
        }
    }

    return RedirectToAction("Manage");
}

My problem is similar to MVC5 ApplicationUser custom properties, but that seems to use an older version of Identity because the IdentityManager class doesn't seem to exist.

Can someone guide me on how to update User info in the database?

UPDATE: If I include all the fields in the register form, all the values are stored in the appropriate field in a new record of the Users table from the database.

I don't know to make changes to the fields of an existing user (row in the users table). UserManager.UpdateAsync(user) doesn't work.

Also note my issue is more Identity oriented than EntityFramework

This question is related to asp.net-mvc asp.net-mvc-5 asp.net-identity

The answer is


The OWIN context allows you to get the db context. Seems to be working fine so far me, and after all, I got the idea from the ApplciationUserManager class which does the same thing.

    internal void UpdateEmail(HttpContext context, string userName, string email)
    {
        var manager = context.GetOwinContext().GetUserManager<ApplicationUserManager>();
        var user = manager.FindByName(userName);
        user.Email = email;
        user.EmailConfirmed = false;
        manager.Update(user);
        context.GetOwinContext().Get<ApplicationDbContext>().SaveChanges();
    }

The UserManager did not work, and As @Kevin Junghans wrote,

UpdateAsync just commits the update to the context, you still need to save the context for it to commit to the database

Here is quick solution (prior to new features in ASP.net identity v2) I used in a web forms projetc. The

class AspNetUser :IdentityUser

Was migrated from SqlServerMembership aspnet_Users. And the context is defined:

public partial class MyContext : IdentityDbContext<AspNetUser>

I apologize for the reflection and synchronous code--if you put this in an async method, use await for the async calls and remove the Tasks and Wait()s. The arg, props, contains the names of properties to update.

 public static void UpdateAspNetUser(AspNetUser user, string[] props)
 {
     MyContext context = new MyContext();
     UserStore<AspNetUser> store = new UserStore<AspNetUser>(context);
     Task<AspNetUser> cUser = store.FindByIdAsync(user.Id); 
     cUser.Wait();
     AspNetUser oldUser = cUser.Result;

    foreach (var prop in props)
    {
        PropertyInfo pi = typeof(AspNetUser).GetProperty(prop);
        var val = pi.GetValue(user);
        pi.SetValue(oldUser, val);
    }

    Task task = store.UpdateAsync(oldUser);
    task.Wait();

    context.SaveChanges();
 }

I am using .Net Core 3.1 or higher version.Please follow the solution:

  public class UpdateAssignUserRole
    {
        public string username { get; set; }
        public string rolename { get; set; }
        public bool IsEdit { get; set; }

    }

 private async Task UpdateSeedUsers(UserManager<IdentityUser> userManager, UpdateAssignUserRole updateassignUsername)
        {
            IList<Users> Users = await FindByUserName(updateassignUsername.username);

            if (await userManager.FindByNameAsync(updateassignUsername.username) != null)
            {
                var user = new IdentityUser
                {
                    UserName = updateassignUsername.username,
                    Email = Users[0].Email,
 
                };
                var result = await userManager.FindByNameAsync(updateassignUsername.username);
                if (result != null)
                {
                    IdentityResult deletionResult = await userManager.RemoveFromRolesAsync(result, await userManager.GetRolesAsync(result));
                    if (deletionResult != null)
                    {
                        await userManager.AddToRoleAsync(result, updateassignUsername.rolename);
                    }
                }
            }

        }

If you leave any of the fields for ApplicationUser OR IdentityUser null the update will come back as successful but wont save the data in the database.

Example solution:

ApplicationUser model = UserManager.FindById(User.Identity.GetUserId())

Add the newly updated fields:

model.Email = AppUserViewModel.Email;
model.FName = AppUserViewModel.FName;
model.LName = AppUserViewModel.LName;
model.DOB = AppUserViewModel.DOB;
model.Gender = AppUserViewModel.Gender;

Call UpdateAsync

IdentityResult result = await UserManager.UpdateAsync(model);

I have tested this and it works.


I also had problems using UpdateAsync when developing a version of SimpleSecurity that uses ASP.NET Identity. For example, I added a feature to do a password reset that needed to add a password reset token to the user information. At first I tried using UpdateAsync and it got the same results as you did. I ended up wrapping the user entity in a repository pattern and got it to work. You can look at the SimpleSecurity project for an example. After working with ASP.NET Identity more (documentation is still non-existent) I think that UpdateAsync just commits the update to the context, you still need to save the context for it to commit to the database.


Based on your question and also noted in comment.

Can someone guide me on how to update User info in the database?

Yes, the code is correct for updating any ApplicationUser to the database.

IdentityResult result = await UserManager.UpdateAsync(user);

  • Check for constrains of all field's required values
  • Check for UserManager is created using ApplicationUser.

UserManager<ApplicationUser> UserManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));


I have tried the functionality in the same way and when i call UserManager.Updateasync method it succeeds but there is no update in the database. After spending some time i found another solution to update the data in aspnetusers table which is following:

1) you need to create UserDbContext class inheriting from IdentityDbContext class like this:

public class UserDbContext:IdentityDbContext<UserInfo>
{
    public UserDbContext():
        base("DefaultConnection")
    {
        this.Configuration.ProxyCreationEnabled = false;
    }
}

2) then in Account controller update user information like this:

UserDbContext userDbContext = new UserDbContext();
userDbContext.Entry(user).State = System.Data.Entity.EntityState.Modified;
await userDbContext.SaveChangesAsync();

where user is your updated entity.

hope this will help you.


I am using the new EF & Identity Core and I have the same issue, with the addition that I've got this error:

The instance of entity type cannot be tracked because another instance of this type with the same key is already being tracked.

With the new DI model I added the constructor's Controller the context to the DB.

I tried to see what are the conflict with _conext.ChangeTracker.Entries() and adding AsNoTracking() to my calls without success.

I only need to change the state of my object (in this case Identity)

_context.Entry(user).State = EntityState.Modified;
var result = await _userManager.UpdateAsync(user);

And worked without create another store or object and mapping.

I hope someone else is useful my two cents.


Add the following code to your Startup.Auth.cs file under the static constructor:

        UserManagerFactory = () => new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));

        OAuthOptions = new OAuthAuthorizationServerOptions
        {
            TokenEndpointPath = new PathString("/Token"),
            Provider = new ApplicationOAuthProvider(PublicClientId, UserManagerFactory),
            AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
            AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
            AllowInsecureHttp = true
        };

The UserManagerFactory setting line of code is what you use to associate your custom DataContext with the UserManager. Once you have done that, then you can get an instance of the UserManager in your ApiController and the UserManager.UpdateAsync(user) method will work because it is using your DataContext to save the extra properties you've added to your custom application user.


Excellent!!!

IdentityResult result = await UserManager.UpdateAsync(user);

This works for me. I'm using Identity 2.0, it looks like GetApplicationUser isn't there anymore.

        var user = await UserManager.FindByIdAsync(User.Identity.GetUserId());
        if (!string.IsNullOrEmpty(form["FirstName"]))
        {
            user.FirstName = form["FirstName"];
        }
        if (!string.IsNullOrEmpty(form["LastName"]))
        {
            user.LastName = form["LastName"];
        }
        IdentityResult result = await UserManager.UpdateAsync(user);

Examples related to asp.net-mvc

Using Lato fonts in my css (@font-face) Better solution without exluding fields from Binding Vue.js get selected option on @change You must add a reference to assembly 'netstandard, Version=2.0.0.0 How to send json data in POST request using C# VS 2017 Metadata file '.dll could not be found The default XML namespace of the project must be the MSBuild XML namespace How to create roles in ASP.NET Core and assign them to users? The model item passed into the dictionary is of type .. but this dictionary requires a model item of type How to use npm with ASP.NET Core

Examples related to asp.net-mvc-5

'router-outlet' is not a known element The type or namespace name 'System' could not be found How to get 'System.Web.Http, Version=5.2.3.0? EntityType 'IdentityUserLogin' has no key defined. Define the key for this EntityType How to extend available properties of User.Identity How to implement oauth2 server in ASP.NET MVC 5 and WEB API 2 How to get JSON object from Razor Model object in javascript The model backing the 'ApplicationDbContext' context has changed since the database was created How can I implement a theme from bootswatch or wrapbootstrap in an MVC 5 project? MVC 5 Access Claims Identity User Data

Examples related to asp.net-identity

ASP.NET Core Identity - get current user How to get current user in asp.net core Adding ASP.NET MVC5 Identity Authentication to an existing project How to get the current logged in user Id in ASP.NET Core How to extend available properties of User.Identity Get current user id in ASP.NET Identity 2.0 Get the current user, within an ApiController action, without passing the userID as a parameter ASP.NET Identity - HttpContext has no extension method for GetOwinContext ASP.NET MVC 5 - Identity. How to get current ApplicationUser OWIN Security - How to Implement OAuth2 Refresh Tokens