2016-07-07 56 views
3

當我註冊使用以下代碼用戶:MVC - InvalidOperationException異常:用戶ID未找到

// POST: /Account/Register 
[HttpPost] 
[AllowAnonymous] 
[ValidateAntiForgeryToken] 
public async Task<ActionResult> Register(RegisterViewModel model) 
{ 
    if (ModelState.IsValid) 
    { 
     var user = new ApplicationUser() { UserName = model.UserName }; 

     IdentityResult result = await UserManager.CreateAsync(user, model.Password); 

     if (result.Succeeded) 
     { 
      await SignInAsync(user, isPersistent: false); 
      return RedirectToAction("Index", "Home"); 
     } 
     else 
     { 
      AddErrors(result); 
     } 

     return View(model); 
    } 
} 

我能夠訪問所有與[授權]屬性的看法。 不過,如果我註銷,並與我得到

一個錯誤頁面相同的用戶早在「InvalidOperationException異常:用戶ID找不到」

錯誤似乎從我的SignInAsync功能在未來聲明:

var identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); 

我不是增加一個用戶名並沒有在用戶班組長(它的ID號),或在AspNetUsers表中沒有用戶ID字段。 用戶存在於該表中,但同樣沒有UserId。

我已經嘗試清除cookie等,但仍然沒有運氣重新登錄。 我在做註冊錯誤嗎?我不明白爲什麼認證正在尋找UserId字段,當它似乎不存在

編輯: 當我第一次登錄時......我得到錯誤頁面。但是,當我重新打開頁面並讀取cookie時,我可以訪問所有內容。初次登錄時發生了什麼?

這裏是SignInAsync方法:

private async Task SignInAsync(ApplicationUser user, bool isPersistent) 
     { 
      AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie); 
      var _identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie); 

      AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, _identity); 
     } 

列入

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; 
     } 
    } 
+0

你能分享你的用戶模型嗎? – Neshta

+0

用戶是IPrinicipal實現。我認爲它的烘烤英寸和用戶對象是一個IdentityUser – rigamonk

+0

你可以告訴我們的方法SignInAsync(用戶,isPersistent:false)的實現;?添加了 –

回答

0

編輯:我錯了,你已經提到短小精悍,所以小巧玲瓏,具體細節是不相關的,但解決方案的總體思路仍然存在 - 您的Id和UserId列可能無法正確匹配。


昨天我遇到了這個確切的錯誤。我想你以前曾提到你使用Dapper作爲數據訪問機制。我認爲這也許是相關的,因爲你也提到該表有Userid字段,但是你的用戶類具有Id屬性。我猜你還可能有一些代碼,如果沒有一個,則可以爲Id屬性分配新的Guid。事情是這樣的:

public ApplicationUser() 
{ 
    Id = Guid.NewGuid().ToString(); 
} 

這種結合測繪工作如何小巧玲瓏,可以搞亂您自Id場將風與新Guid,而不是它應該從表中讀取一個。

在下面的示例中,Dapper無法分配ApplicationUser的Id字段,因爲DB字段的名稱與該類的屬性名稱不同。但是它的構造函數已經有了一個Id值。這會導致稍後致電FindByIdAsync()和朋友失敗。

public async Task<ApplicationUser> FindByNameAsync(string userName) 
{ 
    ApplicationUser result = null; 

    using (var conn = await GetOpenDBConnection()) 
    { 
     try 
     { 
      // this query is bugged with Dapper because UserId does not 
      // exist on ApplicationUser. 
      var queryResults = await conn.QueryAsync<ApplicationUser>(
       "SELECT UserId, UserName, Email FROM dbo.Users WHERE UserName = @UserName;", 
       new { UserName = userName }); 

      result = queryResults.FirstOrDefault(); 
     } 
     catch (Exception ex) 
     { 
          //handle error appropriately. 
      result = null; 
     } 
    } 

    return result; 
} 

如果它實際上是一個小巧玲瓏的映射問題,您可以重命名字段在查詢結果,如SELECT UserId as [Id], UserName, Email FROM dbo.Users WHERE UserName = @UserName,或見Randall Stutton's answer對於如何在一個非常乾淨的方式小巧玲瓏的字段映射。