2017-01-22 76 views
0

我已经看到了这个主题中的其他问题,但似乎我错过了某些我从其他问题找不到的东西。也许它与RavenDb.AspNet.Identity有关。无论如何,我无法看到我的代码在哪里做错了。CreateIdentityAsync,RavenDb.AspNet.Identity。例外情况:UserId找不到

当我注册一个用户。一切顺利,保存到RavenDb IdentityUserByUserNameApplicationUser。但是当它登录到await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 时出现问题。并引发错误:“找不到UserId”。

public class ApplicationUser : IdentityUser 
    { 
     public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager) 
     { 
      // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType 
      var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie); 
      // Add custom user claims here 

      return userIdentity; 
     } 
    } 

     //from AccountController start 
     [AllowAnonymous] 
    [ValidateAntiForgeryToken] 
    public async Task<ActionResult> Register(RegisterViewModel model) 
    { 
     if (ModelState.IsValid) 
     { 
      var user = new ApplicationUser { UserName = model.Email, Email = model.Email, Id = "RavenDbUsers/" + model.Email }; 

      var result = await UserManager.CreateAsync(user, model.Password); 
      await AsyncDataSession.SaveChangesAsync(); 

      if (result.Succeeded) 
      { 
       await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 

       return RedirectToAction("Index", "Home"); 
      } 
      AddErrors(result); 
     } 

     // If we got this far, something failed, redisplay form 
     return View(model); 
    } 
    //from AccountController end 


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

UPDATE:

//构造函数,SingInManager,控制器的UserManager

 private ApplicationSignInManager _signInManager; 
    private UserManager<ApplicationUser> _userManager; 

    public AccountController() 
    { 
     _userManager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(() => AsyncDataSession)); 
    } 

    public ApplicationSignInManager SignInManager 
    { 
     get 
     { 
      return _signInManager ?? HttpContext.GetOwinContext().Get<ApplicationSignInManager>(); 
     } 
     private set 
     { 
      _signInManager = value; 
     } 
    } 

    public UserManager<ApplicationUser> UserManager 
    { 
     get 
     { 
      return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); 
     } 
     private set 
     { 
      _userManager = value; 
     } 
    } 

//更新时间:ApplicationUserManager

public class ApplicationUserManager : UserManager<ApplicationUser> 
    { 
    public ApplicationUserManager(IUserStore<ApplicationUser> store) 
      : base(store) 
    { 
    } 

    public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) 
    { 
     var session = context.Get<IAsyncDocumentSession>(); 
     session.Advanced.UseOptimisticConcurrency = true; 

     var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(session)); 
     manager.UserValidator = new UserValidator<ApplicationUser>(manager) 
     { 
      AllowOnlyAlphanumericUserNames = false, 
      RequireUniqueEmail = true 
     }; 

     manager.PasswordValidator = new PasswordValidator 
     { 
      RequiredLength = 6, 
      RequireNonLetterOrDigit = true, 
      RequireDigit = true, 
      RequireLowercase = true, 
      RequireUppercase = true, 
     }; 

     manager.UserLockoutEnabledByDefault = true; 
     manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); 
     manager.MaxFailedAccessAttemptsBeforeLockout = 5; 

     manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser> 
     { 
      MessageFormat = "Your security code is {0}" 
     }); 
     manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser> 
     { 
      Subject = "Security Code", 
      BodyFormat = "Your security code is {0}" 
     }); 
     manager.EmailService = new EmailService(); 
     manager.SmsService = new SmsService(); 
     var dataProtectionProvider = options.DataProtectionProvider; 
     if (dataProtectionProvider != null) 
     { 
      manager.UserTokenProvider = 
        new DataProtectorTokenProvider<ApplicationUser>(dataProtectionProvider.Create("ASP.NET Identity")); 
     } 
     return manager; 
    } 
+0

你发现问题了吗?刚刚在本周早些时候的谈话中跟进。 –

+1

是的,我终于做到了!在控制器的“var result = await UserManager.CreateAsync”这一行,用户被保存到db。但我想,就像你先说的那样,我的UserManager和SignInManager使用不同的会话。所以在那一行之后,我不得不使用我的base raven控制器会话手动存储和保存用户。然后SignInManager可以在db(同一会话)中找到用户。所以我认为这是我的一个错误...非常感谢您分享的帮助和代码。它帮助我找到问题 – user3228992

+0

很高兴提供帮助。如果您有任何RavenDB身份问题,请随时联系。我是Twitter上的@judahgabriel。 –

回答

1

RavenDB.AspNet.Identity的作者在这里。

当你到这一行时,user.Id的值是什么?

await SignInManager.SignInAsync(user, isPersistent: false, rememberBrowser: false); 

此外,您可以验证用户实际存在数据库之前,该代码执行?

我的心理调试技巧告诉我你的UserManager可能使用与accountController.AsyncDataSession不同的IAsyncDocumentSession,因此,当你进行SignInAsync调用时,用户实际上并不在数据库中。

+0

嗨!当我到达那条线时,user.Id就是我分配给它的地方(例如“RavenDbUsers/[email protected]”)。我也可以验证该用户是否存在于数据库中。顺便说一句,感谢一个伟大的项目!但我真的不知道该怎么做......实施中的某些内容必须是错误的...... – user3228992

+0

只需确认,用户在* SignInAsync实际执行之前就存在于DB *中,是的? –

+0

我可以在那时看到在RavenStudio中创建的用户。所以是的,我猜... – user3228992