2016-09-07 22 views
1

我試圖在創建一個默認的ASP.NET核心與「個人用戶帳戶」後,在登錄操作中從用戶對象獲取「id」值並始終返回null。線路(VAR objUser = User.Claims.FirstOrDefault()值;)從像主頁/索引其他行動存取時它User.Claims.FirstOrDefault()。登錄操作時的值爲空(ASP.NET身份3)?

[HttpPost] 
    [AllowAnonymous] 
    [ValidateAntiForgeryToken] 
    public async Task<IActionResult> Login(LoginViewModel model, string returnUrl = null) 
    { 
     ViewData["ReturnUrl"] = returnUrl; 
     if (ModelState.IsValid) 
     { 
      // This doesn't count login failures towards account lockout 
      // To enable password failures to trigger account lockout, set lockoutOnFailure: true 
      var result = await _signInManager.PasswordSignInAsync(model.Email, model.Password, model.RememberMe, lockoutOnFailure: false); 


      if (result.Succeeded) 
      { 

       var objUser = User.Claims.FirstOrDefault().Value; 

       _logger.LogInformation(1, "User logged in."); 
       return RedirectToLocal(returnUrl); 
      } 
      if (result.RequiresTwoFactor) 
      { 
       return RedirectToAction(nameof(SendCode), new { ReturnUrl = returnUrl, RememberMe = model.RememberMe }); 
      } 
      if (result.IsLockedOut) 
      { 
       _logger.LogWarning(2, "User account locked out."); 
       return View("Lockout"); 
      } 
      else 
      { 
       ModelState.AddModelError(string.Empty, "Invalid login attempt."); 
       return View(model); 
      } 
     } 

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

用戶對象不爲空

public IActionResult Index() 
    { 
     var x = User.Claims.FirstOrDefault().Value; 
     return View(); 
    } 

是否有一個在結果後在登錄操作中擁有User對象的方式。成功了嗎?

感謝, AG

+1

爲什麼使用'FirstOrDefault()'的'.Value'?你是否收到錯誤/異常?當然你可以做'var x = User.Claims.FirstOrDefault();'FirstOrDefault()'方法返回對象,如果它找到一個,否則返回null。然後你可以做一個'null'check:'if(x!= null){...}'。 –

+1

或者,如果您想在一行中分配'x',則可以在C#6.0中使用空傳播:'var x = User.Claims.FirstOrDefault()?Value;' –

+0

'用戶'在登錄操作時始終爲空並在其他操作不爲空 – AG70

回答

2

我覺得這裏的問題是,在當時的claimsprincipal用戶登錄被創建和cookie認證中間件將其序列化到被添加到響應的身份驗證cookie所以它會作爲響應的一部分發送到瀏覽器。

由於cookie的機制,您無法讀取cookie,直到瀏覽器將其傳回服務器時的下一個請求。這是因爲您在響應中設置了Cookie,該響應會將Cookie傳遞迴Web瀏覽器,並在Web瀏覽器將Cookie傳遞到服務器時請求Cookie上的Cookie。當帖子登錄時,瀏覽器尚未通過身份驗證cookie,因爲它尚未收到它。你已經在響應中設置了它,但是如前所述從服務器代碼訪問它時,它來自請求而不是響應。

在下一個請求中,cookie作爲頭傳遞,然後cookie認證中間件可以將它從cookie反序列化回ClaimsPrincipal,這就是您的控制器代碼中的「User」。因此,直到下一個請求才能使用填充的用戶和聲明,然後您可以從請求而不是響應獲取請求。

因此,舉例來說,如果你需要選擇基於登錄過程中分配的權利重定向到哪裏,你能做到這一點是重定向到另一個動作和動作的一種方式,因爲它是一個新的請求,將有機會獲得claimsprincipal這是從cookie反序列化,然後可以再次根據索賠重定向。缺點是雙重重定向。

你也可以像你在自己的答案中顯示的那樣查找用戶,如果這給了你所需要的,但是你得到了ApplicationUser或任何代表你的用戶的類,這與ClaimsPrincipal不一樣。

+0

好的測試:-) Joe –

0

我的東西我找到了答案。

var u = await _userManager.FindByEmailAsync(model.Email); 
var u_Id = u.Id; 

感謝, AG