MVC - InvalidOperationException:找不到UserId

时间:2016-07-07 13:11:10

标签: asp.net-mvc authentication

使用以下代码注册用户时:

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

我可以使用[Authorize]属性访问所有视图。 但是,如果我退出并重新登录同一个用户,我会收到错误页面

  

“InvalidOperationException:找不到UserId”

错误似乎来自我在SignInAsync函数中的声明:

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

我没有添加UserID,用户类(其Id)或AspNetUsers表中没有UserId字段。 用户存在于该表中,但同样没有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;
        }
    }

1 个答案:

答案 0 :(得分:0)

编辑:我错了关于被提到你短小精悍,所以小巧玲珑,具体细节是不相关的,但修复的总体思路仍然是 - 你的ID和用户ID列很可能没有得到正确地匹配了

昨天我遇到了这个确切的错误。我想您以前曾提到过您使用Dapper作为数据访问机制。我认为这可能是相关的,因为您还提到该表具有Userid字段,但您的用户类具有Id属性。我猜您可能还有一些代码可以将GuidId分配给public ApplicationUser() { Id = Guid.NewGuid().ToString(); } 属性,如果那里没有。像这样:

Id

这与Dapper映射的工作方式相结合可能会让您感到困扰,因为Guid字段将会结束新的ApplicationUser而不是它应该从表中读取的字段。

在下面的示例中,Dapper无法分配FindByIdAsync()的Id字段,因为DB字段的名称与类的属性不同。但它的构造函数已经有一个Id值。这导致以后呼叫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

如果它实际上是一个小巧玲珑的映射问题,您可以在查询结果中的字段重命名,例如pip install etlalchemy,或见Randall Stutton's answer如何在一个非常干净的方式小巧玲珑的字段映射。