在 VS2015 中的 ASP.NET Identity 中将 User Id 类型更改为 int
Change User Id type to int in ASP.NET Identity in VS2015
默认情况下ASP.NET VS 2015 中的标识使用字符串作为 AspNet*** 表的主键。我想改用 int 类型的 id。经过一些研究,发现框架开箱即用地支持不同类型的 ID。在下面的答案中,我将展示为实现这一目标所做的更改。
更新:添加我的答案后,我在 asp.net 网站上找到了这个博客 post,它描述了相同但更全面的内容:http://www.asp.net/identity/overview/extensibility/change-primary-key-for-users-in-aspnet-identity
IdentityModels.cs
改为:
// New derived classes
public class UserRole : IdentityUserRole<int>
{
}
public class UserClaim : IdentityUserClaim<int>
{
}
public class UserLogin : IdentityUserLogin<int>
{
}
public class Role : IdentityRole<int, UserRole>
{
public Role() { }
public Role(string name) { Name = name; }
}
public class UserStore : UserStore<ApplicationUser, Role, int,
UserLogin, UserRole, UserClaim>
{
public UserStore(ApplicationDbContext context): base(context)
{
}
}
public class RoleStore : RoleStore<Role, int, UserRole>
{
public RoleStore(ApplicationDbContext context): base(context)
{
}
}
// You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more.
public class ApplicationUser : IdentityUser<int, UserLogin, UserRole, UserClaim>
{
public DateTime? ActiveUntil;
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager 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;
}
}
public class ApplicationDbContext : IdentityDbContext<ApplicationUser, Role, int,
UserLogin, UserRole, UserClaim>
{
public ApplicationDbContext()
: base("DefaultConnection")
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
在`App_Start\IdentityConfig.cs中,更改如下类:
public class ApplicationUserManager : UserManager<ApplicationUser, int>
{
public ApplicationUserManager(IUserStore<ApplicationUser, int> store)
: base(store)
{
}
public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context)
{
var manager = new ApplicationUserManager(new UserStore(context.Get<ApplicationDbContext>()));
// Configure validation logic for usernames
manager.UserValidator = new UserValidator<ApplicationUser, int>(manager)
{
AllowOnlyAlphanumericUserNames = false,
RequireUniqueEmail = true
};
// Configure validation logic for passwords
manager.PasswordValidator = new PasswordValidator
{
RequiredLength = 8,
// RequireNonLetterOrDigit = true,
RequireDigit = true,
RequireLowercase = true,
RequireUppercase = true,
};
// Configure user lockout defaults
manager.UserLockoutEnabledByDefault = true;
manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5);
manager.MaxFailedAccessAttemptsBeforeLockout = 5;
// Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user
// You can write your own provider and plug it in here.
manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser, int>
{
MessageFormat = "Your security code is {0}"
});
manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser, int>
{
Subject = "Security Code",
BodyFormat = "Your security code is {0}"
});
manager.EmailService = new EmailService();
manager.SmsService = new SmsService();
var dataProtectionProvider = options.DataProtectionProvider;
if (dataProtectionProvider != null)
{
manager.UserTokenProvider =
new DataProtectorTokenProvider<ApplicationUser, int>(dataProtectionProvider.Create("ASP.NET Identity"));
}
return manager;
}
}
// Configure the application sign-in manager which is used in this application.
public class ApplicationSignInManager : SignInManager<ApplicationUser, int>
{
public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager)
: base(userManager, authenticationManager)
{
}
public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user)
{
return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager);
}
public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context)
{
return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication);
}
}
在 App_Start\Startup.Auth.cs
中将 OnValidateIdentity
属性 更改为:
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>(
validateInterval: TimeSpan.FromMinutes(30),
regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
getUserIdCallback: id => id.GetUserId<int>())
更改 ManageController 以使用新的 pk 类型:
将 User.Identity.GetUserId()
的所有条目替换为 User.Identity.GetUserId<int>()
可能有几个字符串 id
参数需要更改为 int
,仅此而已。
根据 this blog post,使用 ASP.NET 核心标识,进行以下更改:
首先,转到 Data\Migrations
文件夹并删除其中的所有内容。
在Startup.cs
中,在ConfigureServices
方法中,将services.AddIdentity
改为
services.AddIdentity<ApplicationUser, IdentityRole<int>>()
.AddEntityFrameworkStores<ApplicationDbContext, int>()
.AddDefaultTokenProviders();
在 ApplicationDbContext.cs
中将基数 class 从 IdentityDbContext<ApplicationUser>
更改为
public class ApplicationDbContext
: IdentityDbContext<ApplicationUser, IdentityRole<int>, int>
最后,将 ApplicationUser.cs
中的基数 class 从 IdentityUser
更改为
public class ApplicationUser : IdentityUser<int>
然后 运行 add-migration -o Data\Migrations
和 update-database
。如果迁移导致任何问题,请使用 Sql Server Management Studio 或 VS 中的 SqlServerObjectExplorer 删除数据库(不要 只使用文件系统) ,重新删除您的迁移,然后重试。
默认情况下ASP.NET VS 2015 中的标识使用字符串作为 AspNet*** 表的主键。我想改用 int 类型的 id。经过一些研究,发现框架开箱即用地支持不同类型的 ID。在下面的答案中,我将展示为实现这一目标所做的更改。
更新:添加我的答案后,我在 asp.net 网站上找到了这个博客 post,它描述了相同但更全面的内容:http://www.asp.net/identity/overview/extensibility/change-primary-key-for-users-in-aspnet-identity
IdentityModels.cs
改为:// New derived classes public class UserRole : IdentityUserRole<int> { } public class UserClaim : IdentityUserClaim<int> { } public class UserLogin : IdentityUserLogin<int> { } public class Role : IdentityRole<int, UserRole> { public Role() { } public Role(string name) { Name = name; } } public class UserStore : UserStore<ApplicationUser, Role, int, UserLogin, UserRole, UserClaim> { public UserStore(ApplicationDbContext context): base(context) { } } public class RoleStore : RoleStore<Role, int, UserRole> { public RoleStore(ApplicationDbContext context): base(context) { } } // You can add profile data for the user by adding more properties to your ApplicationUser class, please visit http://go.microsoft.com/fwlink/?LinkID=317594 to learn more. public class ApplicationUser : IdentityUser<int, UserLogin, UserRole, UserClaim> { public DateTime? ActiveUntil; public async Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager 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; } } public class ApplicationDbContext : IdentityDbContext<ApplicationUser, Role, int, UserLogin, UserRole, UserClaim> { public ApplicationDbContext() : base("DefaultConnection") { } public static ApplicationDbContext Create() { return new ApplicationDbContext(); } }
在`App_Start\IdentityConfig.cs中,更改如下类:
public class ApplicationUserManager : UserManager<ApplicationUser, int> { public ApplicationUserManager(IUserStore<ApplicationUser, int> store) : base(store) { } public static ApplicationUserManager Create(IdentityFactoryOptions<ApplicationUserManager> options, IOwinContext context) { var manager = new ApplicationUserManager(new UserStore(context.Get<ApplicationDbContext>())); // Configure validation logic for usernames manager.UserValidator = new UserValidator<ApplicationUser, int>(manager) { AllowOnlyAlphanumericUserNames = false, RequireUniqueEmail = true }; // Configure validation logic for passwords manager.PasswordValidator = new PasswordValidator { RequiredLength = 8, // RequireNonLetterOrDigit = true, RequireDigit = true, RequireLowercase = true, RequireUppercase = true, }; // Configure user lockout defaults manager.UserLockoutEnabledByDefault = true; manager.DefaultAccountLockoutTimeSpan = TimeSpan.FromMinutes(5); manager.MaxFailedAccessAttemptsBeforeLockout = 5; // Register two factor authentication providers. This application uses Phone and Emails as a step of receiving a code for verifying the user // You can write your own provider and plug it in here. manager.RegisterTwoFactorProvider("Phone Code", new PhoneNumberTokenProvider<ApplicationUser, int> { MessageFormat = "Your security code is {0}" }); manager.RegisterTwoFactorProvider("Email Code", new EmailTokenProvider<ApplicationUser, int> { Subject = "Security Code", BodyFormat = "Your security code is {0}" }); manager.EmailService = new EmailService(); manager.SmsService = new SmsService(); var dataProtectionProvider = options.DataProtectionProvider; if (dataProtectionProvider != null) { manager.UserTokenProvider = new DataProtectorTokenProvider<ApplicationUser, int>(dataProtectionProvider.Create("ASP.NET Identity")); } return manager; } } // Configure the application sign-in manager which is used in this application. public class ApplicationSignInManager : SignInManager<ApplicationUser, int> { public ApplicationSignInManager(ApplicationUserManager userManager, IAuthenticationManager authenticationManager) : base(userManager, authenticationManager) { } public override Task<ClaimsIdentity> CreateUserIdentityAsync(ApplicationUser user) { return user.GenerateUserIdentityAsync((ApplicationUserManager)UserManager); } public static ApplicationSignInManager Create(IdentityFactoryOptions<ApplicationSignInManager> options, IOwinContext context) { return new ApplicationSignInManager(context.GetUserManager<ApplicationUserManager>(), context.Authentication); } }
在
App_Start\Startup.Auth.cs
中将OnValidateIdentity
属性 更改为:OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>( validateInterval: TimeSpan.FromMinutes(30), regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager), getUserIdCallback: id => id.GetUserId<int>())
更改 ManageController 以使用新的 pk 类型:
将 User.Identity.GetUserId()
的所有条目替换为 User.Identity.GetUserId<int>()
可能有几个字符串 id
参数需要更改为 int
,仅此而已。
根据 this blog post,使用 ASP.NET 核心标识,进行以下更改:
首先,转到 Data\Migrations
文件夹并删除其中的所有内容。
在Startup.cs
中,在ConfigureServices
方法中,将services.AddIdentity
改为
services.AddIdentity<ApplicationUser, IdentityRole<int>>()
.AddEntityFrameworkStores<ApplicationDbContext, int>()
.AddDefaultTokenProviders();
在 ApplicationDbContext.cs
中将基数 class 从 IdentityDbContext<ApplicationUser>
更改为
public class ApplicationDbContext
: IdentityDbContext<ApplicationUser, IdentityRole<int>, int>
最后,将 ApplicationUser.cs
中的基数 class 从 IdentityUser
更改为
public class ApplicationUser : IdentityUser<int>
然后 运行 add-migration -o Data\Migrations
和 update-database
。如果迁移导致任何问题,请使用 Sql Server Management Studio 或 VS 中的 SqlServerObjectExplorer 删除数据库(不要 只使用文件系统) ,重新删除您的迁移,然后重试。