Microsoft.AspNet.Identity 的自定义成员身份 - CreateLocalUser 失败
Posted
技术标签:
【中文标题】Microsoft.AspNet.Identity 的自定义成员身份 - CreateLocalUser 失败【英文标题】:Custom Membership with Microsoft.AspNet.Identity - CreateLocalUser fails 【发布时间】:2013-07-28 11:58:21 【问题描述】:我一直在尝试使用 Visual Studio 2013 在 ASP.NET 4.5 (Microsoft.AspNet.Identity) 中实现新身份功能的自定义版本。经过数小时的尝试,我已经简化了我的代码以使其正常运行。我在下面列出了我的代码。进行本地注册时,会创建数据库表,但 CreateLocalUser 方法失败。我希望有人可以帮助我确定所需的更改。
模型/MembershipModel.cs
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace thePulse.web.Models
public class PulseUser : IUser
public PulseUser()
public PulseUser(string userName)
UserName = userName;
[Key]
public string Id get; set;
[Required]
[StringLength(20)]
public string UserName get; set;
[StringLength(100)]
public string Email get; set;
[Column(TypeName = "Date")]
public DateTime? BirthDate get; set;
[StringLength(1)]
public string Gender get; set;
public class PulseUserClaim : IUserClaim
public PulseUserClaim()
[Key]
public string Key get; set;
public string UserId get; set;
public string ClaimType get; set;
public string ClaimValue get; set;
public class PulseUserSecret : IUserSecret
public PulseUserSecret()
public PulseUserSecret(string userName, string secret)
UserName = userName;
Secret = secret;
[Key]
public string UserName get; set;
public string Secret get; set;
public class PulseUserLogin : IUserLogin
public PulseUserLogin()
public PulseUserLogin(string userId, string loginProvider, string providerKey)
LoginProvider = LoginProvider;
ProviderKey = providerKey;
UserId = userId;
[Key, Column(Order = 0)]
public string LoginProvider get; set;
[Key, Column(Order = 1)]
public string ProviderKey get; set;
public string UserId get; set;
public class PulseRole : IRole
public PulseRole()
public PulseRole(string roleId)
Id = roleId;
[Key]
public string Id get; set;
public class PulseUserRole : IUserRole
public PulseUserRole()
[Key, Column(Order = 0)]
public string RoleId get; set;
[Key, Column(Order = 1)]
public string UserId get; set;
public class PulseUserContext : IdentityStoreContext
public PulseUserContext(DbContext db) : base(db)
Users = new UserStore<PulseUser>(db);
Logins = new UserLoginStore<PulseUserLogin>(db);
Roles = new RoleStore<PulseRole, PulseUserRole>(db);
Secrets = new UserSecretStore<PulseUserSecret>(db);
UserClaims = new UserClaimStore<PulseUserClaim>(db);
public class PulseDbContext : IdentityDbContext<PulseUser, PulseUserClaim, PulseUserSecret, PulseUserLogin, PulseRole, PulseUserRole>
对控制器/AccountController.cs 的更改
public AccountController()
IdentityStore = new IdentityStoreManager(new PulseUserContext(new PulseDbContext()));
AuthenticationManager = new IdentityAuthenticationManager(IdentityStore);
//
// POST: /Account/Register
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
if (ModelState.IsValid)
try
// Create a profile, password, and link the local login before signing in the user
PulseUser user = new PulseUser(model.UserName);
if (await IdentityStore.CreateLocalUser(user, model.Password))
await AuthenticationManager.SignIn(HttpContext, user.Id, isPersistent: false);
return RedirectToAction("Index", "Home");
else
ModelState.AddModelError("", "Failed to register user name: " + model.UserName);
catch (IdentityException e)
ModelState.AddModelError("", e.Message);
// If we got this far, something failed, redisplay form
return View(model);
如上所述,当 CreateLocalUser 方法失败 (Microsoft.AspNet.Identity.EntityFramework) 时,此实现会失败。我不知道为什么。
【问题讨论】:
这是一个示例身份应用程序,它正在做类似于我正在做的事情(供参考)。 github.com/rustd/AspnetIdentitySample/tree/master/… 这是来自 MSDN 博客的一篇文章,描述了 ASP.NET 的新身份系统。 blogs.msdn.com/b/webdev/archive/2013/06/27/… 我也无法实现这一点。我没有找到任何使用包含密码的自定义用户表的示例,但也允许将 google 等帐户链接到数据库中的同一记录的 oAuth 功能。 Phil,以下行(在 AccountController 中)返回 false,并且没有在数据库中创建用户记录。 if (await IdentityStore.CreateLocalUser(user, model.Password)) 这里是另一个查看新 OWIN 表单身份验证的页面:blogs.msdn.com/b/webdev/archive/2013/07/03/… 【参考方案1】:PulseUser.Id 被定义为字符串,但似乎没有设置为值。您是否打算为 Id 使用 GUID?如果是,请在构造函数中对其进行初始化。
public PulseUser() : this(String.Empty)
public PulseUser(string userName)
UserName = userName;
Id = Guid.NewGuid().ToString();
您还需要检查用户名是否不存在。查看在 PulseDbContext 中覆盖 DbEntityValidationResult。在VS2013中新建一个MVC项目看例子。
【讨论】:
谢谢,格兰特。我肯定错过了。但是,我仍然收到相同的错误消息,并且没有进一步的进展。 澄清一下,每次发布任何代码更改时,我都会删除数据库中的所有表。然后,我尝试使用简单的用户名(“Vito”)和密码进行本地注册。每次都创建用户失败。【参考方案2】:这里的问题是 IdentityStoreManager 对身份 EF 模型的默认实现有很强的依赖性。例如,CreateLocalUser 方法将创建 UserSecret 和 UserLogin 对象并将它们保存到商店,如果商店不使用默认模型类型,则该方法将不起作用。因此,如果您自定义模型类型,它将无法与 IdentityStoreManager 顺利配合。
由于您只自定义 IUser 模型,因此我简化了代码以从默认身份用户继承自定义用户并重用身份 EF 模型中的其他模型。
using Microsoft.AspNet.Identity;
using Microsoft.AspNet.Identity.EntityFramework;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity;
using System.Linq;
using System.Web;
namespace WebApplication11.Models
public class PulseUser : User
public PulseUser()
public PulseUser(string userName) : base(userName)
[StringLength(100)]
public string Email get; set;
[Column(TypeName = "Date")]
public DateTime? BirthDate get; set;
[StringLength(1)]
public string Gender get; set;
public class PulseUserContext : IdentityStoreContext
public PulseUserContext(DbContext db) : base(db)
this.Users = new UserStore<PulseUser>(this.DbContext);
public class PulseDbContext : IdentityDbContext<PulseUser, UserClaim, UserSecret, UserLogin, Role, UserRole>
上面的代码应该适用于 Identity API 的预览版。
即将发布的 IdentityStoreManager API 已经意识到了这个问题,并将所有非 EF 依赖代码更改为一个基类,以便您可以通过继承它来自定义它。它应该解决这里的所有问题。谢谢。
【讨论】:
[@Hongye Sun] 你说的预览版指的是什么版本的身份存储?我目前正在引用 1.0.0-beta1?此实现是否允许本地帐户的用户和密码位于自定义用户表中,并且还允许实现其他 oauth 提供程序? 谢谢孙宏业。我肯定会期待这个的发布版本,因为它对于任何大型用户群都几乎无法使用。 我应该能够让它工作实现 IUser 吗?还是我应该总是做 myuser:User?【参考方案3】:由于在转至 RTM 时对此进行了很多更改,因此我更新了 SPA 模板,该模板使用 WebApi 控制器进行所有身份登录等。这是一个非常酷的模板,如果你还没有看过的话。
我把我所有的代码都放在这里: https://github.com/s093294/aspnet-identity-rtm/tree/master
(请注意,它只是为了灵感。我只是让它工作而已。适当地也有一两个错误)。
【讨论】:
以上是关于Microsoft.AspNet.Identity 的自定义成员身份 - CreateLocalUser 失败的主要内容,如果未能解决你的问题,请参考以下文章
Microsoft.AspNet.Identity 的自定义成员身份 - CreateLocalUser 失败
从Microsoft.AspNet.Identity看微软推荐的一种MVC的分层架构
将 Microsoft.AspNet.Identity 升级到 rc1 后找不到 IdentityStoreManager
如何更改 Microsoft.AspNet.Identity.EntityFramework.IdentityUser 中的 id 类型
Microsoft.AspNet.Identity: UserID用整型数据表示, 而不是GUID
实体类型“Microsoft.AspNet.Identity.EntityFramework.IdentityUserLogin<string>”需要定义一个键