2015-01-03 11 views
8

Sto cercando di implementare ruoli utente nella mia applicazione Web MVC. Tuttavia sto ricevendo un'eccezione nulla sulla linea return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); nel mio controller account.MVC5 Account Controller null riferimento eccezione

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 che attiverà l'aggiunta degli utenti al ruolo.

[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 contiene

 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>())); 
    } 
} 

Quando è il riferimento null provenienti da? Nel codice sto verificando due volte che l'utente esiste.

Grazie

risposta

19

Queste sono senza dubbio le linee incriminate ...

var account = new AccountController(); 
if (user != null) account.UserManager.AddToRole(user.Id, RoleName); 

controllori non sono destinate ad essere istanziati in questo modo perché essi sono fortemente legati alla richiesta HTTP corrente (quindi il HttpContext).

Quando viene colpito HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();, HttpContext è nullo perché non esiste un contesto.

È possibile inserire la stessa proprietà nel controller in cui si sta tentando di accedere a UserManager. Funziona perché OwinContext è condiviso nell'intera applicazione.

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"); 
    } 
} 

E se si vuole ottenere davvero fantasia, dichiarare una BaseController che eredita da Controller, mettere la proprietà UserManager all'interno, e hanno tutti gli altri controller ereditano dalla vostra base.

+0

Dio è stato anche così semplice. Grazie mille! – electrometro

+0

Anche questo mi ha preso. È andato alla fantasia e ha creato un controller di base per passare le funzioni universali in altri luoghi in cui ho bisogno. Pensiero brillante! – Dreamcasting

+0

Grazie mille Scarpa –

Problemi correlati