MVC5 帐户控制器空引用异常 [英] MVC5 Account Controller null reference exception

查看:18
本文介绍了MVC5 帐户控制器空引用异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在我的 MVC Web 应用程序中实现用户角色.但是我在 return _userManager ??HttpContext.GetOwinContext().GetUserManager(); 在我的帐户控制器中.

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.

帐户控制器

[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 将触发将用户添加到角色.

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

Startup.Auth does contain

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

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

Where is the null reference coming from? In the code I am double checking that the user exists.

谢谢

推荐答案

这些无疑是有问题的台词...

These are undoubtedly the offending lines...

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

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

Controllers aren't meant to be instantiated in this way because they are heavily tied to the current HTTP request (thus the HttpContext).

HttpContext.GetOwinContext().GetUserManager(); 被命中时,HttpContext 为空,因为没有上下文.

When HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); gets hit, HttpContext is null because there is no context.

您可以简单地将相同的属性放在您尝试访问 UserManager 的控制器中.这是有效的,因为 OwinContext 在整个应用程序中共享.

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

如果你想变得更花哨,声明一个从 Controller 继承的 BaseController,把 UserManager 属性放在里面,然后把所有的您的其他控制器继承自您的基础.

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.

这篇关于MVC5 帐户控制器空引用异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆