Accessing UserManager outside AccountController

Spionred picture Spionred · Mar 27, 2015 · Viewed 29.4k times · Source

I am trying to set the value of a column in aspnetuser table from a different controller (not accountcontroller). I have been trying to access UserManager but I can't figure our how to do it.

So far I have tried the following in the controller I want to use it in:

    ApplicationUser u = UserManager.FindById(User.Identity.GetUserId());
    u.IsRegComplete = true;
    UserManager.Update(u);

This would not compile (I think because UserManager has not been instantiated the controller)

I also tried to create a public method in the AccountController to accept the value I want to change the value to and do it there but I can't figure out how to call it.

public void setIsRegComplete(Boolean setValue)
{
    ApplicationUser u = UserManager.FindById(User.Identity.GetUserId());
    u.IsRegComplete = setValue;
    UserManager.Update(u);

    return;
}

How do you access and edit user data outside of the Account Controller?

UPDATE:

I tried to instantiate the UserManager in the other controller like so:

    var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(db));
    ApplicationUser u = userManager.FindById(User.Identity.GetUserId());

I the project complied (got a little excited) but when I ran the code I get the following error:

Additional information: The entity type ApplicationUser is not part of the model for the current context.

UPDATE 2:

I have moved the function to the IdentityModel (don't ask I am clutching at straws here) like so:

   public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }
        public Boolean IsRegComplete { get; set; }

        public void SetIsRegComplete(string userId, Boolean valueToSet)
        {

            var userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>());
            ApplicationUser u = new ApplicationUser();
            u = userManager.FindById(userId);

            u.IsRegComplete = valueToSet;
            return;
        }
    }

However I am still getting the following:

The entity type ApplicationUser is not part of the model for the current context.

There is also the following class in IdentitiesModels.cs:

public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
    public ApplicationDbContext()
        : base("DefaultConnection", throwIfV1Schema: false)
    {
    }

    public static ApplicationDbContext Create()
    {
        return new ApplicationDbContext();
    }
}

What am I doing wrong here? It feels like I am completely barking up the wrong tree. All I am trying to do is update a column in aspnetuser table from the action of a different controller (i.e not the AccountsController).

Answer

Iravanchi picture Iravanchi · Mar 27, 2015

If you're using the default project template, the UserManager gets created the following way:

In the Startup.Auth.cs file, there's a line like this:

app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);

that makes OWIN pipeline instantiate an instance of ApplicationUserManager each time a request arrives at the server. You can get that instance from OWIN pipeline using the following code inside a controller:

Request.GetOwinContext().GetUserManager<ApplicationUserManager>()

If you look carefully at your AccountController class, you'll see the following pieces of code that makes access to the ApplicationUserManager possible:

    private ApplicationUserManager _userManager;

    public ApplicationUserManager UserManager
    {
        get
        {
            return _userManager ?? Request.GetOwinContext().GetUserManager<ApplicationUserManager>();
        }
        private set
        {
            _userManager = value;
        }
    }

Please note, that in case you need to instantiate the ApplicationUserManager class, you need to use the ApplicationUserManager.Create static method so that you have the appropriate settings and configuration applied to it.