Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-mvc/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在SQL Server上更改ASP.Net Identity 2以创建newSequentialId主键?_Asp.net_Asp.net Mvc_Asp.net Mvc 5_Asp.net Identity_Asp.net Identity 2 - Fatal编程技术网

如何在SQL Server上更改ASP.Net Identity 2以创建newSequentialId主键?

如何在SQL Server上更改ASP.Net Identity 2以创建newSequentialId主键?,asp.net,asp.net-mvc,asp.net-mvc-5,asp.net-identity,asp.net-identity-2,Asp.net,Asp.net Mvc,Asp.net Mvc 5,Asp.net Identity,Asp.net Identity 2,我有一个ASP.NET Identity 2实现(没有用户数据,只有基表),用户ID类型为UNIQUEIDENTIFIER 这个应用程序首先是一个代码,我使用的是EF6 以下是DDL: CREATE TABLE [dbo].[AspNetUsers] ( [Id] UNIQUEIDENTIFIER NOT NULL, [FirstName] NVARCHAR (MAX) NULL, [LastName]

我有一个ASP.NET Identity 2实现(没有用户数据,只有基表),用户ID类型为UNIQUEIDENTIFIER

这个应用程序首先是一个代码,我使用的是EF6

以下是DDL:

CREATE TABLE [dbo].[AspNetUsers] (
    [Id]                   UNIQUEIDENTIFIER NOT NULL,
    [FirstName]            NVARCHAR (MAX) NULL,
    [LastName]             NVARCHAR (MAX) NULL,
    [Email]                NVARCHAR (256) NULL,
    [EmailConfirmed]       BIT            NOT NULL,
    [PasswordHash]         NVARCHAR (MAX) NULL,
    [SecurityStamp]        NVARCHAR (MAX) NULL,
    [PhoneNumber]          NVARCHAR (MAX) NULL,
    [PhoneNumberConfirmed] BIT            NOT NULL,
    [TwoFactorEnabled]     BIT            NOT NULL,
    [LockoutEndDateUtc]    DATETIME       NULL,
    [LockoutEnabled]       BIT            NOT NULL,
    [AccessFailedCount]    INT            NOT NULL,
    [UserName]             NVARCHAR (256) NOT NULL,
    [SubjectId]            INT            DEFAULT ((0)) NOT NULL,
    [SubjectIds]           VARCHAR (50)   NULL,
    [OrganizationId]       INT            DEFAULT ((0)) NOT NULL,
    [OrganizationIds]      VARCHAR (50)   NULL,
    [RoleId]               INT            DEFAULT ((0)) NOT NULL,
    CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED ([Id] ASC)
);


GO
CREATE UNIQUE NONCLUSTERED INDEX [UserNameIndex]
    ON [dbo].[AspNetUsers]([UserName] ASC);
我知道创建的普通GUID是一个普通GUID

有人能告诉我如何创建一个newSequential GUID吗

请注意


我正在寻找正确的方法来实现这一点,特别是使用ASP.Net Identity 2。特别是我想知道是否需要对Identity 2 UserManager等进行任何更改。

我终于能够构建并运行该项目。使用Fluent API创建后,将
newsequentialid()
分配给ID字段:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<ApplicationUser>().Property(t => t.Id)
            .HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<CustomUserRole>().HasKey(x => new
        {
            x.RoleId,
            x.UserId
        });

        modelBuilder.Entity<CustomUserLogin>().HasKey(x => new
        {
            x.UserId,
            x.ProviderKey,
            x.LoginProvider
        });
    }
必须更改其他实体类型:

public class ApplicationUser : IdentityUser<Guid, CustomUserLogin, CustomUserRole,
    CustomUserClaim>
{


    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public override Guid Id { get; set; }

    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, Guid> 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 CustomUserRole : IdentityUserRole<Guid> { }
public class CustomUserClaim : IdentityUserClaim<Guid> { }
public class CustomUserLogin : IdentityUserLogin<Guid> { }

public class CustomRole : IdentityRole<Guid, CustomUserRole>
{
    public CustomRole() { }
    public CustomRole(string name) { Name = name; }
}

public class CustomUserStore : UserStore<ApplicationUser, CustomRole, Guid,
    CustomUserLogin, CustomUserRole, CustomUserClaim>
{
    public CustomUserStore(ApplicationDbContext context)
        : base(context)
    {
    }
}

public class CustomRoleStore : RoleStore<CustomRole, Guid, CustomUserRole>
{
    public CustomRoleStore(ApplicationDbContext context)
        : base(context)
    {
    }
}

public class ApplicationDbContext : IdentityDbContext<ApplicationUser, CustomRole,
    Guid, CustomUserLogin, CustomUserRole, CustomUserClaim>
{
    public ApplicationDbContext()
        : base("DefaultConnection")
    {
    }
替换
userguid
而不是我看到的
userId

我不得不在这里使用
ToString()

BrowserRemembered = await AuthenticationManager.TwoFactorBrowserRememberedAsync(userGuidId.ToString())
在Account Controller中,我似乎只进行了更改

    [AllowAnonymous]
    public async Task<ActionResult> ConfirmEmail(string userId, string code)
    {
        Guid GuidUserId = new Guid(userId);
        if (userId == null || code == null)
        {
            return View("Error");
        }
        var result = await UserManager.ConfirmEmailAsync(GuidUserId, code);
        return View(result.Succeeded ? "ConfirmEmail" : "Error");
    }
[AllowAnonymous]
公共异步任务确认邮件(字符串用户ID、字符串代码)
{
Guid GuidUserId=新的Guid(用户ID);
if(userId==null | | code==null)
{
返回视图(“错误”);
}
var result=await UserManager.confirmemailsync(GuidUserId,代码);
返回视图(result.successed?“确认邮件”:“错误”);
}

首先创建基于“IdentityUser”的类的非通用版本

public class AppUserClaim : IdentityUserClaim<Guid> { }
public class AppUserLogin : IdentityUserLogin<Guid> { }
public class AppUserRole : IdentityUserRole<Guid> { }
。。。最后是
IdentityDbContext

public class AppIdentityContext : IdentityDbContext<AppUser, AppRole, Guid, AppUserLogin, AppUserRole, AppUserClaim>
{
    public AppIdentityContext()
        : base("name=AspNetIdentity")
    {
    }
}
在构造函数中,我们使用
UuidCreateSequential
函数创建一个新ID,并通过
ID
属性返回该ID。我想将数据库中的
Id
列设置为使用
newsequentialid()
作为默认值,并使用它而不是
DllImport
,但我还没有解决这个问题

要在控制器操作中使用:

public async Task<ActionResult> ActionName()
{
    AppIdentityContext dbContext = new AppIdentityContext();
    AppUserStore store = new AppUserStore(dbContext);
    AppUserManager manager = new AppUserManager(store);
    AppUser user = new AppUser { UserName = "<name>", Email = "<email>" };

    await manager.CreateAsync(user);

    return this.View();
}
public异步任务ActionName()
{
AppIdentityContext dbContext=新的AppIdentityContext();
AppUserStore=新的AppUserStore(dbContext);
AppUserManager=新的AppUserManager(商店);
AppUser=新的AppUser{UserName=”“,Email=“”};
wait manager.CreateAsync(用户);
返回这个.View();
}
需要注意的几点:

  • 如果您使用的是现有数据库,即使用SQL脚本创建的数据库,
    AspNetUsers
    中的
    Id
    列为
    nvarchar
    ,则需要将以下列更改为
    唯一标识符

    public class AppUser : IdentityUser<Guid, AppUserLogin, AppUserRole, AppUserClaim>
    {
        [DllImport("rpcrt4.dll", SetLastError = true)]
        private static extern int UuidCreateSequential(out Guid guid);
    
        private Guid _id;
    
        public AppUser()
        {
            UuidCreateSequential(out _id);
        }        
    
        /// <summary>
        /// User ID (Primary Key)
        /// </summary>
        public override Guid Id
        {
            get { return _id; }
            set { _id = value; }
        }
    }
    
    • AspNetUsers.Id
    • AspNetRoles.Id
    • AspNetUserRoles.UserId
    • AspNetUserRoles.RoleId
  • 在ASP.NET MVC控制器的
    IIdentity
    接口上使用
    GetUserId
    扩展方法,即
    this.User.Identity.GetUserId()
    ,将返回一个
    字符串,因此在将返回值转换为字符串时必须使用以下方法:

    新Guid(this.User.Identity.GetUserId())

    此方法有一个通用版本,但在其下面使用了
    Convert.ChangeType
    ,它需要在实现
    IConvertable
    中传递值,而
    Guid
    不需要

  • 我还不能完全测试这个,但如果它不能完全满足您的需求,希望它能提供一个有用的基础

    更新#1:以下是我经历的步骤:

  • 创建无身份验证的新ASP.NET MVC应用程序
  • 添加以下NuGet包

    • 实体框架
    • Microsoft.AspNet.Identity.Core
    • Microsoft.AspNet.Identity.EntityFramework
  • 将所有代码示例添加到
    App\u Start
    文件夹中名为
    Identity.cs
    的文件中

    注意:排除控制器操作示例。这将在步骤6中完成

  • web.config

  • 将名为
    AspNetIdentity的新连接字符串添加到
    web.config
  • 将控制器操作示例添加到
    家庭控制器上的
    索引
    操作中,并更换
    部件
  • 将名为
    AspNetIdentity
    的新空数据库添加到SQL Server
  • 运行应用程序

  • 如果您使用的ASP.NET MVC模板选择了“个人用户帐户身份验证”选项,则会出现一些必须修复的错误。这些主要围绕着将对
    IdentityUser*
    类的引用更改为新的基于
    AppUser*
    的类,并替换对
    User.Identity.GetUserId()的调用
    使用我原始答案中步骤#2中提供的代码示例。

    这是我使Guid类型的角色和用户Id字段具有默认值或绑定的
    newsequentialid()

  • 删除Visual Studio中迁移文件夹中的*.cs文件
  • 在数据库中删除表\uu迁移历史记录和所有AspNet*
  • 将以下代码添加到ApplicationDbContext类:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<ApplicationUser>().Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<ApplicationRole>().Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }
    
    模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
    {
    基于模型创建(modelBuilder);
    modelBuilder.Entity().Property(t=>t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    modelBuilder.Entity().Property(t=>t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }
    
  • 在Visual Studio软件包管理器控制台中运行
    添加迁移初始值
  • 在Visual Studio软件包管理器控制台中运行
    更新数据库

  • 警告:这将从您的数据库中删除所有角色用户

    这其中的哪一部分使其具有顺序?@Stilga
    public class AppUserClaim : IdentityUserClaim<Guid> { }
    public class AppUserLogin : IdentityUserLogin<Guid> { }
    public class AppUserRole : IdentityUserRole<Guid> { }
    
    public class AppRole : IdentityRole<Guid, AppUserRole> 
    { 
    }
    
    public class AppUserStore : UserStore<AppUser, AppRole, Guid, AppUserLogin, AppUserRole, AppUserClaim>
    {
        public AppUserStore(DbContext context)
            : base(context)
        {
        }
    }
    
    public class AppUserManager : UserManager<AppUser, Guid>
    {
        public AppUserManager(IUserStore<AppUser, Guid> store)
            : base(store)
        {
        }
    }
    
    public class AppIdentityContext : IdentityDbContext<AppUser, AppRole, Guid, AppUserLogin, AppUserRole, AppUserClaim>
    {
        public AppIdentityContext()
            : base("name=AspNetIdentity")
        {
        }
    }
    
    public class AppUser : IdentityUser<Guid, AppUserLogin, AppUserRole, AppUserClaim>
    {
        [DllImport("rpcrt4.dll", SetLastError = true)]
        private static extern int UuidCreateSequential(out Guid guid);
    
        private Guid _id;
    
        public AppUser()
        {
            UuidCreateSequential(out _id);
        }        
    
        /// <summary>
        /// User ID (Primary Key)
        /// </summary>
        public override Guid Id
        {
            get { return _id; }
            set { _id = value; }
        }
    }
    
    public async Task<ActionResult> ActionName()
    {
        AppIdentityContext dbContext = new AppIdentityContext();
        AppUserStore store = new AppUserStore(dbContext);
        AppUserManager manager = new AppUserManager(store);
        AppUser user = new AppUser { UserName = "<name>", Email = "<email>" };
    
        await manager.CreateAsync(user);
    
        return this.View();
    }
    
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.Entity<ApplicationUser>().Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
        modelBuilder.Entity<ApplicationRole>().Property(t => t.Id).HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
    }