I am trying to implement user roles into my MVC web application. However I am getting a null exception on the line return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
in my account controller.
Account Controller
[Authorize]
public class AccountController : Controller
{
private ApplicationSignInManager _signInManager;
private ApplicationUserManager _userManager;
private ApplicationRoleManager _roleManager;
public AccountController(){}
public AccountController(ApplicationUserManager userManager, ApplicationSignInManager signInManager, ApplicationRoleManager roleManager)
{ UserManager = userManager;
SignInManager = signInManager;
RoleManager = roleManager; }
public ApplicationRoleManager RoleManager
{
get { return _roleManager ?? HttpContext.GetOwinContext().Get<ApplicationRoleManager>(); }
private set { _roleManager = value; }
}
public ApplicationSignInManager SignInManager
{
get { return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>(); }
private set { _signInManager = value; }
}
public ApplicationUserManager UserManager
{
get { return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); }
private set {_userManager = value; }
}
ActionResult that will trigger the adding of the user to the role.
[System.Web.Mvc.HttpPost]
[ValidateAntiForgeryToken]
public ActionResult RoleAddToUser(string UserName, string RoleName)
{
ApplicationUser user = context.Users.FirstOrDefault(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase));
var account = new AccountController();
if (user != null) account.UserManager.AddToRole(user.Id, RoleName);
var list = context.Roles.OrderBy(r => r.Name).ToList().Select(rr => new SelectListItem { Value = rr.Name.ToString(), Text = rr.Name }).ToList();
ViewBag.Roles = list;
return View("ManageUserRoles");
}
Startup.Auth does contain
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);
Identity Config
// Configure the application sign-in manager which is used in this application.
public class ApplicationSignInManager : SignInManager<ApplicationUser, string>
{
public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
: base(userManager, authenticationManager)
{
}
public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
{ return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager); }
public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
{ return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication); }
}
public class ApplicationRoleManager : RoleManager<IdentityRole>
{
public ApplicationRoleManager(IRoleStore<IdentityRole, string> roleStore)
: base(roleStore) { }
public static ApplicationRoleManager Create(IdentityFactoryOptions<ApplicationRoleManager> options, IOwinContext context)
{
return new ApplicationRoleManager(new RoleStore<IdentityRole>(context.Get<ApplicationDbContext>()));
}
}
Where is the null reference coming from? In the code I am double checking that the user exists.
Thanks
These are undoubtedly the offending lines...
var account = new AccountController();
if (user != null) account.UserManager.AddToRole(user.Id, RoleName);
Controllers aren't meant to be instantiated in this way because they are heavily tied to the current HTTP request (thus the HttpContext
).
When HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();
gets hit, HttpContext
is null because there is no context.
You can simply put the same property in your controller where you are trying to access the UserManager. This works because the OwinContext is shared across your entire application.
public class HomeController : Controller
{
public ApplicationUserManager UserManager
{
get { return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); }
private set {_userManager = value; }
}
public ActionResult RoleAddToUser(string UserName, string RoleName)
{
ApplicationUser user = context.Users.FirstOrDefault(u => u.UserName.Equals(UserName, StringComparison.CurrentCultureIgnoreCase));
if (user != null) UserManager.AddToRole(user.Id, RoleName);
//Other code...
return View("ManageUserRoles");
}
}
And if you want to get really fancy, declare a BaseController
that inherits from Controller
, put the UserManager
property inside, and have all your other controllers inherit from your base.
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