简体   繁体   English

MVC5客户控制器空引用异常

[英]MVC5 Account Controller null reference exception

I am trying to implement user roles into my MVC web application. 我正在尝试在MVC Web应用程序中实现用户角色。 However I am getting a null exception on the line return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 但是我在return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();的行上得到一个空异常return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 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. 将触发将用户添加到角色的ActionResult。

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

        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 ). 并不是要以这种方式实例化控制器,因为它们与当前的HTTP请求(因此HttpContext )紧密相关。

When HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); gets hit, HttpContext is null because there is no context. 被击中, HttpContext为空,因为没有上下文。

You can simply put the same property in your controller where you are trying to access the UserManager. 您可以在试图访问UserManager的控制器中简单地放置相同的属性。 This works because the OwinContext is shared across your entire application. 之所以可行,是因为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");
    }
}

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. 而且,如果您真的想花哨的话,请声明一个继承自ControllerBaseController ,将UserManager属性放入其中,并使所有其他控制器都继承自您的基础。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM