使用以下代码注册用户时:
// 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;
}
}
答案 0 :(得分:0)
编辑:我错了关于被提到你短小精悍,所以小巧玲珑,具体细节是不相关的,但修复的总体思路仍然是 - 你的ID和用户ID列很可能没有得到正确地匹配了
昨天我遇到了这个确切的错误。我想您以前曾提到过您使用Dapper作为数据访问机制。我认为这可能是相关的,因为您还提到该表具有Userid
字段,但您的用户类具有Id
属性。我猜您可能还有一些代码可以将Guid
新Id
分配给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如何在一个非常干净的方式小巧玲珑的字段映射。