2016-07-07 54 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对于如何在一个非常干净的方式小巧玲珑的字段映射。