我一直在尝试使用Visual Studio 2013在ASP.NET 4.5(Microsoft.AspNet.Identity)中实现新的Identity功能的自定义版本。经过许多个小时的播放,我已经简化了我的代码努力让它运行没有错误。我在下面列出了我的代码做本地注册时,创建数据库表,但CreateLocalUser方法失败。我希望有人可以帮助我识别所需的变化。
Models / 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)时,此实现将失败。我不知道为什么。
解决方法
这里的问题是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依赖代码更改为基类,以便您可以通过继承来自定义它。应该解决这里的一切问题。谢谢。