Need to change Asp.Net Identity (RTM) User Id from

2019-02-10 16:42发布

Using Asp.Net Identity 1.0 (RTM version). The default implementation creates an AspNetUsers table. The Id column type is nvarchar(128).

When the database and tables are being created, I would simply like to change the type of the User Id to be uniqueidentifier instead of nvarchar(128). I have attempted this using .HasColumnType("uniqueidentifier") within the OnModelCreating override... but it throws errors.

Microsoft indicates that it is easy... but I would tend to disagree...

http://www.asp.net/identity/overview/getting-started/introduction-to-aspnet-identity

Since you control the database schema, common tasks such as changing table names or changing the data type of primary keys is simple to do.

So according to their extremely brief and completely non-technical documentation this seems to be a common task, changing the data type of a primary key... but there doesn't seem to be anything simple about it. Please help.

2条回答
不美不萌又怎样
2楼-- · 2019-02-10 17:23

If you update to the latest nightly bits, you can try out the new 1.1-alpha1 apis which should make this easier now: Here's what plugging in Guids instead of strings should look like for example

    public class GuidRole : IdentityRole<Guid, GuidUserRole> { 
        public GuidRole() {
            Id = Guid.NewGuid();
        }
        public GuidRole(string name) : this() { Name = name; }
    }
    public class GuidUserRole : IdentityUserRole<Guid> { }
    public class GuidUserClaim : IdentityUserClaim<Guid> { }
    public class GuidUserLogin : IdentityUserLogin<Guid> { }

    public class GuidUser : IdentityUser<Guid, GuidUserLogin, GuidUserRole, GuidUserClaim> {
        public GuidUser() {
            Id = Guid.NewGuid();
        }
        public GuidUser(string name) : this() { UserName = name; }
    }

    private class GuidUserContext : IdentityDbContext<GuidUser, GuidRole, Guid, GuidUserLogin, GuidUserRole, GuidUserClaim> { }
    private class GuidUserStore : UserStore<GuidUser, GuidRole, Guid, GuidUserLogin, GuidUserRole, GuidUserClaim> {
        public GuidUserStore(DbContext context)
            : base(context) {
        }
    }
    private class GuidRoleStore : RoleStore<GuidRole, Guid, GuidUserRole> {
        public GuidRoleStore(DbContext context)
            : base(context) {
        }
    }

    [TestMethod]
    public async Task CustomUserGuidKeyTest() {
        var manager = new UserManager<GuidUser, Guid>(new GuidUserStore(new GuidUserContext()));
        GuidUser[] users = {
            new GuidUser() { UserName = "test" },
            new GuidUser() { UserName = "test1" }, 
            new GuidUser() { UserName = "test2" },
            new GuidUser() { UserName = "test3" }
            };
        foreach (var user in users) {
            UnitTestHelper.IsSuccess(await manager.CreateAsync(user));
        }
        foreach (var user in users) {
            var u = await manager.FindByIdAsync(user.Id);
            Assert.IsNotNull(u);
            Assert.AreEqual(u.UserName, user.UserName);
        }
    }
查看更多
乱世女痞
3楼-- · 2019-02-10 17:40

Hao Kung from the ASP.NET team has posted here on StackOverflow that you need to implement your own IUserStore, but he is working on making it easier for the 1.1 version.

I believe you will not only have to implement IUserStore, to me it looks like you need your own UserStore implementation as the UserStore<TUser> is restricted to IdentityUser.

If I am correct this means that you need to at least implement IUserStore, IUserPasswordStore, IUserSecurityStampStore and IUserLoginStore.

It's 14 methods, most of them pretty straight forward to implement though. Note this would not be a complete replacement for UserStore<TUser>, it's only what you need to support the parts that are used from the AccountController from the default templates.

I have a project on GitHub where I tried this myself, i.e. I implemented a UserStore that use MongoDb instead of EntityFramework for persistence.

查看更多
登录 后发表回答