2017-01-22 78 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