2015-01-03 12 views
8

Próbuję wprowadzić role użytkownika do mojej aplikacji internetowej MVC. Jednak otrzymuję wyjątek zerowy na linii return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); w moim kontrolerze konta.Kontroler konta MVC5 zerowy wyjątek odniesienia

Konto 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 że spowoduje dodanie użytkownika do roli.

[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 robi zawierać

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

Gdzie jest zerowy odniesienia bierze? W kodzie sprawdzam podwójnie, czy użytkownik istnieje.

Dzięki

Odpowiedz

19

Są to niewątpliwie linie obrażając ...

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

Sterowniki nie są przeznaczone do instancji w ten sposób, ponieważ są one mocno przywiązany do bieżącego żądania HTTP (stąd HttpContext).

Po uzyskaniu trafienia HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();, HttpContext ma wartość null, ponieważ nie ma kontekstu.

Możesz po prostu umieścić tę samą właściwość w kontrolerze, gdy próbujesz uzyskać dostęp do UserManager. Działa to, ponieważ OwinContext jest współdzielony w całej aplikacji.

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

A jeśli chcesz uzyskać naprawdę fantazyjne, zadeklarować BaseController która dziedziczy Controller umieścić właściwość UserManager wewnątrz, i wszystkie inne kontrolery dziedziczą z bazy.

+0

Boże, to też było takie proste. Wielkie dzięki! – electrometro

+0

Ten też mnie dostał. Przeszedłem po fantazyjnej trasie i stworzyłem kontroler bazowy, aby przekazywał uniwersalne funkcje do innych miejsc, w których potrzebuję. Genialne myślenie! – Dreamcasting

+0

Bardzo dziękuję Shoe –

Powiązane problemy