MVC5 帐户控制器空引用异常

本文关键字:引用 异常 控制器 MVC5 | 更新日期: 2023-09-27 18:35:55

我正在尝试在我的MVC Web应用程序中实现用户角色。但是,我在帐户控制器中的行return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();上收到空异常。

帐户控制器

[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; }
    }

操作结果,将触发将用户添加到角色。

    [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 确实包含

        app.CreatePerOwinContext(ApplicationDbContext.Create);
        app.CreatePerOwinContext<ApplicationRoleManager>(ApplicationRoleManager.Create);
        app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
        app.CreatePerOwinContext<ApplicationSignInManager>(ApplicationSignInManager.Create);

身份配置

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

空引用从何而来?在代码中,我正在仔细检查用户是否存在。

谢谢

MVC5 帐户控制器空引用异常

这些无疑是冒犯性的台词......

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

控制器不应该以这种方式实例化,因为它们与当前 HTTP 请求(因此HttpContext )密切相关。

HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();被命中时,HttpContext为 null,因为没有上下文。

您只需将相同的属性放在您尝试访问用户管理器的控制器中即可。这是有效的,因为 OwinContext 是在整个应用程序中共享的。

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

如果你想变得非常花哨,请声明一个继承自ControllerBaseController,将UserManager属性放在里面,并让所有其他控制器从你的基继承。