扩展ASP.NET Identity使用Int作主键

当咱们默认新建一个ASP.NET MVC项目的时候,使用的身份认证系统是ASP.NET Identity.
可是这里的Identity使用的主键为String类型的GUID.固然这是大多数系统首先类型.
可是由于历史缘由,而咱们公司全部项目主键都是用的Int类型(这里不讨论int和GUID的优劣)
因此默认的String类型GUID就不能知足咱们的需求,因此进行一些扩展,让其支持Int类型。
下图为默认使用String作主键的ASP.NET MVC
QQ截图20150624104458
数据库

ApplicationUser继承自IdentityUser,而IdentityUser继承/实现
IdentityUser<string, IdentityUserLogin, IdentityUserRole, IdentityUserClaim>, IUser, IUser<string>
这样就使得主键为string类型了,其中IentityUser,IdentityUserLogin,IdentityUserRole,IdentityUserClaim都是<string>
因此生成默认的数据库里的表结构成了下图这样,主键都为nvarchar
QQ截图20150624105533QQ截图20150624105623
安全

接下来,扩展为Int主键首先增长以下几个类
app

public class ApplicationUserLogin : IdentityUserLogin<int> { }
    public class ApplicationUserCliam : IdentityUserClaim<int> { }
    public class ApplicationUserRole : IdentityUserRole<int> { }
    public class ApplicationRole : IdentityRole<int, ApplicationUserRole>, IRole<int> {
        public string Description { get; set; }
        public ApplicationRole() { }
        public ApplicationRole(string name)
            : this()
        {
            this.Name = name;
        }
        public ApplicationRole(string name, string description)
            : this(name)
        {
            this.Description = description;
        }
    }

ApplicationUserLogin  继承自IdentityUserLogin<int>
ApplicationUserCliam  继承自IdentityUserClaim<int>
ApplicationUserRole   继承自IdentityUserRole<int>
ApplicationRole       继承自IdentityRole<int, ApplicationUserRole>, IRole<int>
在Role里还增长了一个属性Deacription(默认实体里只有Id,Name)
作了这步后。其实在Code first中,咱们就已经把实体的结构主键修改成int型了,
只要用这个对应实体Update到数据库中的话。主键会修改为int
而后咱们还要对应ASP.NET MVC的一些改造才能够适应现有的模板
而后咱们将ApplicationUser修改

asp.net

public class ApplicationUser : IdentityUser
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
{
// 请注意,authenticationType 必须与 CookieAuthenticationOptions.AuthenticationType 中定义的相应项匹配
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// 在此处添加自定义用户声明
return userIdentity;
}
}

修改成:
async


public class ApplicationUser
: IdentityUser
<int, ApplicationUserLogin, ApplicationUserRole, ApplicationUserCliam>, IUser<int>
{
public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, int> manager)
{
// 请注意,authenticationType 必须与 CookieAuthenticationOptions.AuthenticationType 中定义的相应项匹配
var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
// 在此处添加自定义用户声明
return userIdentity;
}
}

接下来咱们要修改数据库上下文ApplicationDbContext
QQ截图20150624112544
修改成
ide


public class ApplicationDbContext
: IdentityDbContext
<ApplicationUser, ApplicationUserRole, int,
ApplicationUserLogin, ApplicationUserRole, ApplicationUserCliam
>
{
public ApplicationDbContext()
:
base("DefaultConnection")
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}

而后在增长以下两个类
post


public class ApplicationUserStore
: UserStore
<ApplicationUser, ApplicationRole, int,
ApplicationUserLogin, ApplicationUserRole, ApplicationUserCliam
>,
IUserStore
<ApplicationUser, int>,
IDisposable
{
public ApplicationUserStore(DbContext context)
:
base(context)
{ }
public ApplicationUserStore()
:
this(new IdentityDbContext())
{
base.DisposeContext = true;
}
}
public class ApplicationRoleStore
: RoleStore
<ApplicationRole, int, ApplicationUserRole>,
IQueryableRoleStore
<ApplicationRole, int>,
IRoleStore
<ApplicationRole>,
IDisposable
{
public ApplicationRoleStore()
:
base(new IdentityDbContext())
{
base.DisposeContext = true;
}


上面的几处代码全修改在IdentityModels.cs文件中this

而后修改App_Start\IdentityConfig.cs
在类ApplicationUserManager和ApplicationSignInManager中
把里面全部继承自<ApplicationRole>泛型的地址所有都修改成<ApplicationRole,int>
public class ApplicationUserManager : UserManager<ApplicationUser,int>
public ApplicationUserManager(IUserStore<ApplicationUser, int> store)
manager.UserValidator = new UserValidator<ApplicationUser, int>(manager)
manager.RegisterTwoFactorProvider("电话代码", new PhoneNumberTokenProvider<ApplicationUser,int>
manager.RegisterTwoFactorProvider("电子邮件代码", new EmailTokenProvider<ApplicationUser,int>
public class ApplicationSignInManager : SignInManager<ApplicationUser, int>spa

在App_Start\Startup.Auth.cs
把配置登录Cookie的代码修改成
.net

app.UseCookieAuthentication(new CookieAuthenticationOptions
            {
                AuthenticationType = DefaultAuthenticationTypes.ApplicationCookie,
                LoginPath = new PathString("/Account/Login"),
                Provider = new CookieAuthenticationProvider
                {
                    // 当用户登陆时使应用程序能够验证安全戳。
                    // 这是一项安全功能,当你更改密码或者向账户添加外部登陆名时,将使用此功能。
                    OnValidateIdentity = SecurityStampValidator.OnValidateIdentity<ApplicationUserManager, ApplicationUser, int>(
                        validateInterval: TimeSpan.FromMinutes(30),
                        regenerateIdentityCallback: (manager, user) => user.GenerateUserIdentityAsync(manager),
                        getUserIdCallback: (claim) => int.Parse(claim.GetUserId()))
                    //regenerateIdentity: (manager, user) => user.GenerateUserIdentityAsync(manager))
                }
            });

到此,全部的扩展都已经修改完成,接下来就只要修改相关的View和Controller
在AccountController和ManageController中,
主要是把用到User.Identity.GetUserId()的地方修改成User.Identity.GetUserId<int>();
这样使得拿到的主键由string变成了int

接下来运行程序包管理控制台,生成数据库脚本并执行到数据库


PM> Enable-Migrations
正在检查上下文的目标是否为现有数据库...
已为项目 IntegerDemo 启用 Code First 迁移。
PM> Add-Migration FirstInit
正在为迁移“FirstInit”搭建基架。
此迁移文件的设计器代码包含当前 Code First 模型的快照。在下一次搭建迁移基架时,将使用此快照计算对模型的更改。若是对要包含在此迁移中的模型进行其余更改,则您可经过再次运行“Add-Migration FirstInit”从新搭建基架。
PM> Update-Database
指定“-Verbose”标志以查看应用于目标数据库的 SQL 语句。
正在应用显式迁移: [201506240620390_FirstInit]。
正在应用显式迁移: 201506240620390_FirstInit。
正在运行 Seed 方法。


再看咱们的数据库,已经把主键全都变成了int
QQ截图20150624142400QQ截图20150624142412


相关文档资料
http://www.asp.net/identity
http://typecastexception.com/post/2014/07/13/ASPNET-Identity-20-Extending-Identity-Models-and-Using-Integer-Keys-Instead-of-Strings.aspx
转载请标明出处:http://giantliu.com

</span><span style="color: #0000ff">public</span><span style="color: #000000"> ApplicationRoleStore(DbContext context) : </span><span style="color: #0000ff">base</span><span style="color: #000000">(context) { } }</span></pre></div>
相关文章
相关标签/搜索