2015-01-03 8 views
8

MVC Webアプリケーションにユーザーロールを実装しようとしています。しかし、私のアカウントコントローラのreturn _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();行でnull例外が発生しています。MVC5アカウントコントローラのnull参照例外

アカウント・コントローラ役割へのユーザーの追加をトリガする

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

[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はnull参照から来ている

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

が含まれていますか?コードでは、ユーザーが存在することを二重に確認しています。それらは重く、現在のHTTP要求に関連付けられているため、これらは間違いなく問題のあるラインです

おかげ

答えて

19

は...

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

コントローラは、この方法でインスタンス化することを意味するものではない(したがってHttpContext )。

HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>();がヒットした場合、コンテキストがないためHttpContextはヌルです。

UserManagerにアクセスしようとしているコントローラに同じプロパティを設定するだけで済みます。これは、OwinContextがアプリケーション全体で共有されているために機能します。

​​

そして、あなたが本当に空想を取得したい場合は、Controllerから継承BaseControllerを宣言するには、内部UserManagerプロパティを入れて、すべての他のコントローラは、お使いのベースを継承しています。

+0

神様もとてもシンプルでした。本当にありがとう! – electrometro

+0

これも私には分かりました。幻想的なルートを歩き、普遍的な機能を必要とする他の場所に渡すためのベースコントローラーを作成しました。賢明な考え方! – Dreamcasting

+0

ありがとうたくさんの靴 –