18

I've used ASP.NET Identity 2 for creating role but the result of HttpContext.GetOwinContext().GetUserManager<AppRoleManager>() was null.

Then I couldn't create the role.

How can I solve this problem?

public class MVCController : Controller
{
    public MVCController()
    {

    }
    public AppRoleManager RoleManager // returns null ?!
    {
        get
        {
            return HttpContext.GetOwinContext().GetUserManager<AppRoleManager>();
        }
    }
    public User CurrentUser
    {
        get
        {
            string currentUserId = User.Identity.GetUserId();
            User currentUser = DataContextFactory.GetDataContext().Users.FirstOrDefault(x => x.Id.ToString() == currentUserId);
            return currentUser;
        }
    }
    public IAuthenticationManager AuthManager
    {
        get
        {

            return HttpContext.GetOwinContext().Authentication;
        }
    }
    public AppUserManager UserManager
    {
        get
        {
            return HttpContext.GetOwinContext().GetUserManager<AppUserManager>();
        }
    }
} 

My Controller:

public class RoleAdminController : MVCController
{
    [HttpPost]
    public async Task<ActionResult> CreateRole([Required]string name)
    {
        if (ModelState.IsValid)
        {
            if (RoleManager != null) // RoleManager is null, why?!
            {
                IdentityResult result = await RoleManager.CreateAsync(new Role { Name = name });
                if (result.Succeeded)
                {
                    return RedirectToAction("Index");
                }
                else
                {
                    AddErrorsFromResult(result);
                }
            }
        }
        return View(name);
    }
}

AppRoleManager:

public class AppRoleManager : RoleManager<Role, int>, IDisposable
{
    public AppRoleManager(RoleStore<Role, int, UserRole> store)
        : base(store)
    {
    }
    public static AppRoleManager Create(IdentityFactoryOptions<AppRoleManager> options, IOwinContext context)
    {
        return new AppRoleManager(new RoleStore<Role, int, UserRole>(DataContextFactory.GetDataContext()));
    }
}
x19
  • 8,277
  • 15
  • 68
  • 126

2 Answers2

37

Most likely you have missed giving OwinContext the way to create ApplicationUserManager.
For that you'll need to have these in your public void Configuration(IAppBuilder app)

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

This will register delegates that create UserManager and RoleManager with OwinContext and only after that you can call these back in your controllers.

trailmax
  • 34,305
  • 22
  • 140
  • 234
  • first line is added already but when I added second line of your code to it, I got an error.... Compiler Error Message: CS1928: 'Owin.IAppBuilder' does not contain a definition for 'CreatePerOwinContext' and the best extension method overload 'Owin.AppBuilderExtensions.CreatePerOwinContext(Owin.IAppBuilder, System.Func)' has some invalid arguments – x19 Oct 13 '14 at 22:23
  • 1
    @Jahan appologies, corrected my answer, it should be `AppRoleManager` as a generic parameter in the second line. – trailmax Oct 13 '14 at 22:30
  • 1
    method location: project>startup.cs – Vasil Valchev Jun 08 '15 at 09:15
  • 3
    AppRoleManager not exist – Vasil Valchev Jul 06 '15 at 07:09
  • AppRoleManager is a custom class, not included in the templates. Here's a good tutorial for how to create one http://bitoftech.net/2015/03/11/asp-net-identity-2-1-roles-based-authorization-authentication-asp-net-web-api/ – Simon_Weaver Dec 06 '17 at 01:21
  • @Simon_Weaver code for this class is in the question, exactly as in your linked article. – trailmax Dec 06 '17 at 01:59
  • @trailmax so it is! I guess I was misled by the 3 people that upvoted it not existing. Don’t know why they didn’t just put it in the templates. Thx – Simon_Weaver Dec 06 '17 at 08:10
  • One notable thing is that the generic method `GetUserManager` is used for roles OR users. It's really just a wrapper and doesn't know anything about users or roles – Simon_Weaver Dec 07 '17 at 19:20
  • Where to look when I added those lines but still have a null UserManager ? I've checked while debugging : the lines are called at startup all right. And when I want to access the ApplicationUserManager, I only got a null. Any idea ? – Augustin Bocken Feb 12 '18 at 10:28
  • 1
    @AugustinBocken Does `ApplicationUserManager.Create` return anything? – trailmax Feb 12 '18 at 11:09
  • It did, but I was able to remove the issue by starting all over again. I must have added something that caused conflict somewhere... Thanks tough ! – Augustin Bocken Feb 12 '18 at 14:54
  • dear @trailmax I'm new to this stuff, I have a same issue like this question. but my case is little different , can you help me in this [link] (https://stackoverflow.com/questions/52978861/usermanager-and-context-getowincontext-getusermanager-applicationusermanager) – Ali Eshghi Oct 26 '18 at 20:56
  • @AliEshghi your fix will be exactly the same. – trailmax Oct 26 '18 at 22:43
  • In my case I also had to add this line ```app.CreatePerOwinContext(ApplicationDbContext.Create);``` as shown here : https://github.com/postsharp/PostSharp.Samples/blob/master/Framework/PostSharp.Samples.MiniProfiler/App_Start/Startup.Auth.cs – Sagick Dec 15 '22 at 20:11
0

I know it's old post , but I want to share my researches with others, for this issue I created partial class and add all my owin references there:

public partial class Startup
    {
        public void ConfigureAuth(IAppBuilder app)
        {
            // Configure the db context, user manager and signin manager to use a single instance per request
            app.CreatePerOwinContext(IdentityModels.Create);
            app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
            app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
app.CreatePerOwinContext<AppRoleManager>(AppRoleManager.Create);

            app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login"),
                Provider = new CookieAuthenticationProvider
                {
                    // Enables the application to validate the security stamp when the user logs in.
                    // This is a security feature which is used when you change a password or add an external login to your account.  
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                validateInterval: TimeSpan.FromMinutes(30),
                regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                }
            });


        }
    }

then I utilize this method in other partial startup :

  public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            ConfigureAuth(app);
        }
    }
Ali Eshghi
  • 1,131
  • 1
  • 13
  • 30