65.9K
CodeProject 正在变化。 阅读更多。
Home

ASP.NET Identity 2.0 主键从字符串更改为整数

starIconstarIconstarIconstarIconstarIcon

5.00/5 (14投票s)

2014 年 6 月 1 日

CPOL

3分钟阅读

viewsIcon

104579

downloadIcon

1540

ASP.NET 团队发布了 Identity 框架 2.0。新版本包含一些新功能,例如泛型主键。本文介绍如何将主键从字符串更改为整数并将其与 MVC5 一起使用。

引言

对于某些项目,用户条目跟踪至关重要。一个常见的例子是会计软件。Asp.net identity framework 1.0 将 userId 使用字符串(128 个字符)。如果应用程序处理大量数据,那么由于字符串匹配,检索包含用户信息的信息可能会变慢。在这种情况下,整数是最佳解决方案。

最新的 Identity framework 2.0 带来了一些新功能。其中之一是泛型主键。所以现在,我们可以将主键设置为整数或其他任何我们喜欢的数据类型。Identity 2.0 包含在 Visual Studio 2013 update 2(发布于 2014 年 5 月 12 日)中。

使用代码

在本文中,我们将通过以下步骤将主键数据类型从字符串更改为整数

使用 Visual Studio 2013 update 2 创建一个 MVC 项目

让我们使用 Visual Studio 2013 创建一个名为 Identity2IntPK 的新ASP.Net Web 应用程序。然后选择MVC并勾选Individual User Account选项。

Visual Studio 2013 MVC 模板将创建一个类似下图所示的结构。

IdentityConfig 文件包含一个名为 ApplicationUserManager 的类,我们可以在其中设置密码强度。

Startup.Auth 包含一个部分类 Startup。在这里,我们可以设置第三方登录提供商,例如 Facebook、Google 等。

IdentityModels 包含 ApplicationUser 和 ApplicationDbContext。基本上,我们将要修改这个文件。

AccountViewModels 包含一些用于数据传输和验证的类。

AccountController 只包含 AccountController 类,它负责登录、注册、密码重置等。

Account 文件夹包含一些视图文件,例如 Login.cshtml、Register.cshtml、ResetPassword.cshtml。

 

 

创建和修改 Identity 类

我们需要修改以下文件来完成此任务。

  1. IdentityModels.cs
  2. IdentityConfig.cs
  3. Startup.Auth.cs

1. IdentityModels.cs:打开 Modules 文件夹中的文件,然后添加 UserRoleIntPk、UserClaimIntPk、UserLoginIntPk、RoleIntPk、UserStoreIntPk、RoleStoreIntPk 类。

    //New drived classes 
    public class UserRoleIntPk : IdentityUserRole<int>
    {        
    }

    public class UserClaimIntPk : IdentityUserClaim<int>
    {        
    }

    public class UserLoginIntPk : IdentityUserLogin<int>
    {        
    }

    public class RoleIntPk : IdentityRole<int, UserRoleIntPk>
    {
        public RoleIntPk() { }
        public RoleIntPk(string name) { Name = name; }
    }

    public class UserStoreIntPk : UserStore<ApplicationUser, RoleIntPk, int, 
        UserLoginIntPk, UserRoleIntPk, UserClaimIntPk>
    {
        public UserStoreIntPk(ApplicationDbContext context)
            : base(context)
        {
        }
    }

    public class RoleStoreIntPk : RoleStore<RoleIntPk, int, UserRoleIntPk>
    {
        public RoleStoreIntPk(ApplicationDbContext context)
            : base(context)
        {
        }
    }

同时修改同一文件中的 ApplicationUser 和 ApplicationDbContext。

    //change bellow classes
    public class ApplicationUser : IdentityUser<int, UserLoginIntPk, UserRoleIntPk, UserClaimIntPk>
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(ApplicationUserManager manager)
        {
            var userIdentity = await manager.CreateIdentityAsync(this, 
                               DefaultAuthenticationTypes.ApplicationCookie);

            // Add custom user claims here
            return userIdentity;
        }
    }

    public class ApplicationDbContext : IdentityDbContext<ApplicationUser, RoleIntPk, int, 
        UserLoginIntPk, UserRoleIntPk, UserClaimIntPk>
    {
        public ApplicationDbContext()
            : base("DefaultConnection")
        {
        }

        public static ApplicationDbContext Create()
        {
            return new ApplicationDbContext();
        }
    }

 

2. IdentityConfig.cs:打开 App_Start 文件夹中的此文件,然后修改 ApplicationUserManager 类。修改后,ApplicationUserManager 将如下所示:

    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 UserStoreIntPk(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 = 6,
                //RequireNonLetterOrDigit = true,
                //RequireDigit = true,
                //RequireLowercase = true,
                //RequireUppercase = true,
            };
            manager.RegisterTwoFactorProvider("PhoneCode", new PhoneNumberTokenProvider<ApplicationUser, int>
            {
                MessageFormat = "Your security code is: {0}"
            });
            manager.RegisterTwoFactorProvider("EmailCode", 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;
        }
    }  

我们在这里将 <ApplicationUser> 替换为  <ApplicationUser, int>

 

3. Startup.Auth.cs:打开 App_Start 文件夹中的此文件,并用新代码替换旧代码。

//old code 
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
//New code 
OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>
    (
         validateInterval: TimeSpan.FromMinutes(30),
         regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
         getUserIdCallback: (id) => (Int32.Parse(id.GetUserId()))
    ) 

修改 AccountController 以适应新的主键

我们的工作几乎完成了。如果编译代码,您会发现大约有 16 个错误,并且所有错误都集中在 AccountController.cs 文件中。因此,我们需要修改此文件以适应新系统。

打开 AccountController.cs 文件,将所有 userId 类型从字符串更改为整数。然后,除了 LinkLogin 函数外,将所有 User.Identity.GetUserId() 替换为 int.Parse(User.Identity.GetUserId())。

同时修改 LinkLoginCallback 为

//
// GET: /Account/LinkLoginCallback
public async Task<ActionResult> LinkLoginCallback()
{
    var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync(XsrfKey, User.Identity.GetUserId());
    if (loginInfo == null)
    {
        return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
    }
    IdentityResult result = await UserManager.AddLoginAsync(int.Parse(User.Identity.GetUserId()), loginInfo.Login);
    if (result.Succeeded)
    {
        return RedirectToAction("Manage");
    }
    return RedirectToAction("Manage", new { Message = ManageMessageId.Error });
} 

运行应用程序

现在编译您的项目,如果一切正常,则运行它。从导航菜单点击注册并添加一个用户。

Entity framework 将为您创建一个包含 AspNet 授权表的数据库。如果您想查看数据库中发生了什么,请从服务器资源管理器中打开 DefaultConnection。右键单击 AspNetUsers 表并选择“打开表定义”,您将看到 id 现在是整数而不是字符串。

关注点

Identity 2 rất tốt vì nó đi kèm với rất nhiều thứ hữu ích. Nhưng hệ thống identity mặc định có thể không phải lúc nào cũng tương thích với tất cả các ứng dụng. Đó là lý do tại sao bài viết này có thể hữu ích cho những ai muốn khả năng mở rộng cao hơn.

历史

First version: 2014年6月1日

© . All rights reserved.