如何更改 Microsoft.AspNet.Identity.EntityFramework.IdentityUser 中的 id 类型

2023-12-08

(ASP.NET MVC 5、EF6、VS2013)

我正在想办法将“Id”字段的类型从 string 更改为 int在类型中:

Microsoft.AspNet.Identity.EntityFramework.IdentityUser

以便让新用户帐户与整数 ID 而不是 GUID 关联。但这似乎比简单地在我的派生用户类中添加一个类型为 int 的新 Id 属性更复杂。看一下这个方法签名:

(来自程序集 Microsoft.AspNet.Identity.Core.dll)

public class UserManager<TUser> : IDisposable where TUser : global::Microsoft.AspNet.Identity.IUser
  {
  ...
  public virtual Task<IdentityResult> AddLoginAsync(string userId, UserLoginInfo login);
  ...
  }

因此,ASP.NET 身份框架中似乎还有其他方法需要 userId 为字符串。我还需要重新实现这些课程吗?

为什么我不想在用户表中存储 id 的 GUID 的解释:

- 还有其他表通过外键将数据与用户表相关联。 (当用户在网站上保存内容时。)我认为没有理由使用更大的字段类型并花费额外的数据库空间,而且没有明显的优势。 (我知道还有其他关于使用 GUID 与 int id 的帖子,但似乎很多人都认为 int id 更快并且使用更少的空间,这仍然让我感到困惑。)

-我计划公开一个静态端点以允许用户检索有关特定用户的数据。我认为:

/users/123/name

/users/{af54c891-69ba-4ddf-8cb6-00d368e58d77}/name

有谁知道为什么 ASP.NET 团队决定以这种方式实现 ID?我尝试将其更改为 int 类型是否目光短浅? (也许我缺少一些好处。)

谢谢...

-Ben


Using a 斯特凡·塞布拉克的回答和本·福斯特的精彩博客文章ASP.NET 身份被剥离我提出了以下解决方案,并将其应用于 ASP.NET Identity2.0由 Visual Studio 2013 生成AccountController.

该解决方案使用整数作为用户的主键,并且还允许获取当前登录用户的 ID,而无需访问数据库。

以下是您需要遵循的步骤:

1.创建自定义用户相关类

默认情况下,AccountController使用类,这些类正在使用string,作为主键的一种类型。我们需要创建以下类,它将使用int反而。我已在一个文件中定义了以下所有类:AppUser.cs

public class AppUser :
    IdentityUser<int, AppUserLogin, AppUserRole, AppUserClaim>,
    IUser<int>
{

}

public class AppUserLogin : IdentityUserLogin<int> { }

public class AppUserRole : IdentityUserRole<int> { }

public class AppUserClaim : IdentityUserClaim<int> { }

public class AppRole : IdentityRole<int, AppUserRole> { }

拥有一个自定义的 ClaimsPrincipal 也很有用,它可以轻松暴露用户的 ID

public class AppClaimsPrincipal : ClaimsPrincipal
{
    public AppClaimsPrincipal( ClaimsPrincipal principal ) : base( principal )
    { }

    public int UserId
    {
        get { return int.Parse(this.FindFirst( ClaimTypes.Sid ).Value); }
    }
}

2. 创建自定义IdentityDbContext

我们的应用程序的数据库上下文将扩展IdentityDbContext,它默认实现所有与身份验证相关的 DbSet。即使DbContext.OnModelCreating是一个空方法,我不确定IdentityDbContext.OnModelCreating,所以重写时,记得调用base.OnModelCreating( modelBuilder ) AppDbContext.cs

public class AppDbContext :
    IdentityDbContext<AppUser, AppRole, int, AppUserLogin, AppUserRole, AppUserClaim>
{
    public AppDbContext() : base("DefaultConnection")
    {
        // Here use initializer of your choice
        Database.SetInitializer( new CreateDatabaseIfNotExists<AppDbContext>() );
    }


    // Here you define your own DbSet's



    protected override void OnModelCreating( DbModelBuilder modelBuilder )
    {
        base.OnModelCreating( modelBuilder );

        // Here you can put FluentAPI code or add configuration map's
    }
}

3. 创建自定义UserStore and UserManager,上面将使用

AppUserStore.cs

public interface IAppUserStore : IUserStore<AppUser, int>
{

}

public class AppUserStore :
    UserStore<AppUser, AppRole, int, AppUserLogin, AppUserRole, AppUserClaim>,
    IAppUserStore
{
    public AppUserStore() : base( new AppDbContext() )
    {

    }

    public AppUserStore(AppDbContext context) : base(context)
    {

    }
}

AppUserManager.cs

public class AppUserManager : UserManager<AppUser, int>
{
    public AppUserManager( IAppUserStore store ) : base( store )
    {

    }
}

4. 修改AccountController使用您的自定义类

全部更改UserManager to AppUserManager, UserStore to AppUserStore等等。举个这个构造函数的例子:

public AccountController()
    : this( new AppUserManager( new AppUserStore( new AppDbContext() ) ) )
{
}

public AccountController(AppUserManager userManager)
{
    UserManager = userManager;
}

5. 添加用户 ID 作为声明ClaimIdentity存储在cookie中

在第 1 步中,我们创建了AppClaimsPrincipal,它公开了从中取出的 UserIdClaimType.Sid。但是,要使此声明可用,我们需要在用户登录时添加它。在AccountController a SingInAsync方法负责登录。我们需要向该方法添加一行,以添加声明。

private async Task SignInAsync(AppUser user, bool isPersistent)
{
    AuthenticationManager.SignOut(DefaultAuthenticationTypes.ExternalCookie);
    ClaimsIdentity identity = await UserManager.CreateIdentityAsync(user, DefaultAuthenticationTypes.ApplicationCookie);

    // Extend identity claims
    identity.AddClaim( new Claim( ClaimTypes.Sid, user.Id.ToString() ) );

    AuthenticationManager.SignIn(new AuthenticationProperties() { IsPersistent = isPersistent }, identity);
}

6. 创建一个BaseController with a CurrentUser财产

要轻松访问控制器中当前登录的用户 ID,请创建一个摘要BaseController,您的控制器将从中派生。在里面BaseController, 创建一个CurrentUser如下:

public abstract class BaseController : Controller
{
    public AppClaimsPrincipal CurrentUser
    {
        get { return new AppClaimsPrincipal( ( ClaimsPrincipal )this.User ); }
    }


    public BaseController()
    {

    }
}

7. 继承你的控制器BaseController享受

从现在开始,您可以使用CurrentUser.UserId在您的控制器中访问当前登录用户的 ID,而无需访问数据库。您可以使用它来仅查询属于用户的对象。

您不必关心用户主键的自动生成 - 毫不奇怪,实体框架在创建表时默认使用 Identity 作为整数主键。

Warning!请记住,如果您在已发布的项目中实现它,则对于已登录的用户ClaimsType.Sid将不存在并且FindFirst将返回 nullAppClaimsPrincipal。您需要强制注销所有用户或处理这种情况AppClaimsPrincipal

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何更改 Microsoft.AspNet.Identity.EntityFramework.IdentityUser 中的 id 类型 的相关文章

  • .net 4.7 中的依赖注入?

    我对 DI 有哪些集成选项有点困惑 我发现它对于 net core 对于我的特定项目 来说非常简单 但我不需要构建跨平台应用程序 也看不到使用 core 的优势 但是 net 框架应用程序似乎仍然使用 Global asax 设置且没有 S
  • 将 Javascript 类数组传递给 MVC 控制器?

    我正在尝试将一系列服务传递给我的控制器 我尝试了很多不同的方法来让它工作 在进入控制器之前序列化数据 序列化每个服务 唯一有效的方法是将控制器参数更改为字符串并序列化数组 然后使用 JsonConvert 但我 d 宁愿不这样做 使用指定的
  • 应用程序内的 SQLite 文件版本兼容性

    我有一个 C NET 应用程序 一种复杂的计算应用程序 其中用户输入数据 处理后的信息使用 JSON 序列化和 EF 保存到 SQLite 文件中 需要时可以将其加载到我们的应用程序中 应用程序在开发过程中经历了很多变化 类也被修改 因此
  • 如何为客户端和服务器缓存设置不同的缓存过期时间

    我想让某些页面为客户端提供 10 分钟缓存 为服务器提供 24 小时缓存 原因是如果页面发生变化 客户端将在 10 分钟内获取更新版本 但如果没有任何变化 服务器只需每天重建一次页面 问题在于输出缓存设置似乎覆盖了客户端设置 这是我的设置
  • 如何根据 ASP.NET VNEXT MVC6 中给出的路径进行虚拟路由/重定向?

    我有一个网站 它在不同的路径上公开多个 API 每个 API 由特定于应用程序部分的控制器处理 例如example com Api Controller Action param1 stuff 其中控制器发生变化 但操作保持相当一致 我有几
  • ASP.NET MVC 子操作的路由匹配

    子动作的路由匹配方法与普通动作有什么不同吗 换句话说 子操作是否有一些自动生成的 url 来进行与父操作类似的匹配 父级或子级动作处理没有区别 任何操作都遵循您在中设置的相同路线定义Application Start 这意味着父母的行为以及
  • 阻止未确认电子邮件的用户使用 Identity 2 登录 ASP.Net MVC

    在 Microsoft Identity 2 中 用户可以确认我从以下位置下载了 Identity 2 示例项目的电子邮件地址here https www nuget org packages Microsoft AspNet Identi
  • ASP.NET MVC 应用程序中的工作单元模式

    我一直在看这个优秀的blog http www nhforge org wikis patternsandpractices nhibernate and the unit of work pattern aspx标题为 NHibernat
  • Visual Studio 智能感知搞砸了

    所以我是 MVC4 和 C 的新手 我已经设计这个网站大约两周了 智能感知没有任何问题 两天来 Visual studio 告诉我 Viewbag 和其他 命令不是我的项目的一部分 我可能错过了一些东西 或者它告诉我 Viewbag 在当前
  • 构建 ViewModel 的合适粒度是多少?

    我正在开发一个新项目 在看到以前项目的一些困难后 这些项目没有提供足够的视图与模型的分离 特别是使用 MVC 模型和视图开始有点相互渗透 我想使用 MVVM 我了解基本概念 并且很高兴开始使用它 然而 有一件事我有点忽略 ViewModel
  • 不支持 EF6 上下文类型“System.Data.Entity.Core.Objects.ObjectContext”

    我有一个使用 Visual Studio 2013 和 ADO NET 实体数据模型 EF6 创建的新项目 现在我必须使用一些动态数据函数 例如访问 MetaTable 对象 所以我添加以下代码 MetaModel model new Me
  • 类型中的属性名称必须是唯一的

    我正在使用 Entity Framework 5 并且有以下实体 public class User public Int32 Id get set public String Username get set public virtual
  • IsReusable 属性中的上下文切换

    是否可重用属性 下面是我的理解IsReusable财产 如果处理程序返回静态内容 将值设置为 true 是安全的 但如果线程返回动态内容 为了使其线程安全 IsReusable应设置为 false 在这种情况下 可能会发生上下文切换 这可能
  • ASP.NET MVC,控制器可以改变提交的值吗?

    ASP NET MVC 中是否允许更改提交的值 HttpPost public ActionResult Create Person toCreate toCreate Lastname toCreate Lastname A return
  • 如何获取 EF 中与组合(键/值)列表匹配的记录?

    我有一个数据库表 其中包含每个用户 年份组合的记录 如何使用 EF 和用户 ID 年份组合列表从数据库获取数据 组合示例 UserId Year 1 2015 1 2016 1 2018 12 2016 12 2019 3 2015 91
  • 实体框架 - SQL Server 2005 - IIS 服务器日期时间问题

    我正在使用 MVC3 和实体框架 在我的应用程序中 我需要通过 EF 调用 SQL Server 2005 中的存储过程来根据以下内容搜索一些数据datetime传递的参数 在当地环境中一切似乎都运行良好 但是将其托管到 IIS 后 我在尝
  • 缺少添加控制器/视图的上下文菜单

    我已将 ASP NET MVC 4 集成到现有的 asp net 网站中 两者都工作正常 但我没有看到任何菜单 快捷方式来在 Visual Studio IDE 中创建控制器 视图 这些仅适用于 ASP NET MVC 模板吗 这些仅适用于
  • Asp.net Identity 注销其他用户

    我正在使用 Asp net Identity 来验证用户身份 并尝试从管理端锁定任何用户 但是当我锁定任何在线用户时 它并没有注销 我读过很多关于我的问题的评论 但它们都不起作用 我尝试使用 UserManager UpdateSecuri
  • 无法将 MVC 4 部署到服务器

    我的 Web 应用程序只是一个用 VS 2010 MVC 4 制作的简单 Web 应用程序 没有任何外部代码 它只是 VS 2010 的默认应用程序 我有 Plesk 的豪华 Windows 托管 我从未更改过帐户中的任何功能 我将所有文件
  • 表单身份验证 MVC4

    我正在尝试使用 MVC4 网站进行简单的表单身份验证设置 在App start FilterConfig cs中 public static void RegisterGlobalFilters GlobalFilterCollection

随机推荐

  • 迭代多个选择/文件夹项目

    我看了一眼MailItem并且没有看到任何表明我可以移动所选项目的信息 我有可以运行的代码 但是Set objItem GetCurrentItem 线路只接收一封邮件 我正在寻找ForEach通过文件夹 或者ForEach通过选择 我尝试
  • ClassCastException DataSource 无法转换为 javax.sql.ConnectionPoolDataSource

    我收到这个异常 java lang ClassCastException org apache tomcat jdbc pool DataSource cannot be cast to javax sql ConnectionPoolDa
  • 为什么使用“git rm”而不是“rm”来删除文件?

    在 SVN 上 直接从文件系统中删除某些内容 而不是使用 svn 会带来很多麻烦 我在使用时没有发现这是一个问题git 但我注意到 git 有它自己的rm执行 git rm 有什么区别rm and git rm 如果你只是使用rm 你需要跟
  • 画布宽度和高度均为 100% 时质量较差

    我用画布做了一个非常小的例子 它可以在JsFiddle http jsfiddle net yPtr5
  • 如何使用A*算法找到最佳的3条路线

    在 A 中 通常您得到的结果只是一条路径 对于给定的出发地和目的地 是否有可能根据 A 有 3 条推荐路径 所以第二个返回的是第二最佳路径 第三个返回的是第三最佳路径 我正在考虑也许以某种方式修改启发式以反映第二和第三最佳路径 你们觉得怎么
  • 填写特定工作表中多列中的空白单元格

    I have the following columns Score Name Last Name 5460 Name1 Lastname1 2620 340 470 3445 Name2 Lastname2 1290 1170 7460
  • 一键提交两份表格

    我有两种 HTML 表单 一种使用 PHP 在输入数据库时 提交数据 另一种将用户引导至 paypal 付款页面 我的问题是用户必须提交这两种表单 这当然是我不希望他们这样做的得做 有没有办法对两种表单使用一个提交按钮 欢迎使用 JavaS
  • 将 openCV 查找表 (LUT) 应用于图像

    我想申请定制颜色查找表 LUT 在图像上 我已经看过了openCV LUT Api但我似乎无法做对 bin bash coding utf 8 import os import numpy as np import cv2 b max 23
  • pty 终端数据包模式 TIOCPKT

    如果我启动一个终端 我如何知道它以什么模式启动 谁决定呢 我可以以数据包模式启动我的终端吗 TIOCPKT 我遇到了这个包模式链接说 Packet mode is enabled by pushing the pckt module on
  • UnicodeDecodeError,无效的连续字节

    为什么以下项目失败 为什么 latin 1 编解码器能够成功 o a test of xe9 char I want this to remain a string as this is what I am receiving v o de
  • 对类中变量的线程安全访问

    在可能有多个线程运行的应用程序中 并且不确定是否在多线程环境下访问这些方法的可能性 但为了安全起见 我做了一个测试类来演示一种情况 一种方法has被编程为线程安全 如果做得正确 也请发表评论 但其余的则不是 在这样的情况下 里面只有一行代码
  • 大 (> 4mb) 文件附件

    使用 Microsoft Graph API 可以将文件附件添加到消息中 如下所述here 但是 由于 REST 请求的总大小限制为 4mb 因此不允许包含非常大的附件 A 可恢复上传会话允许更大的上传 可以通过提供下载链接的参考附件进行引
  • 使用 Android Parse 的多个组合“或”查询

    在 Android 的 Parse 中 是否可以对多个 OR 子查询进行 AND 操作 我一直在尝试组合两个 OR 查询 但没有成功 根据我的研究 Parse 可能不具备这种能力 不过 我还没有找到任何东西来证实 否认这一点 例如 给定一堆
  • 如何使位图透明?

    param bitmap The source bitmap param opacity a value between 0 completely transparent and 255 completely opaque return T
  • Java 8 中方法引用的外部参数

    我希望将外部参数传递给方法引用 String prefix The number is numbers forEach Main printWithPrefix private static void printWithPrefix Int
  • 保护目录免遭直接 URL 访问

    需要一些帮助 我需要保护所有的FOLDERS in a DIRECTORY from direct URL使用权 我可以这样做吗 htaccess如果是 怎么办 或者他们是更安全的方法 这是我的情况 我允许用户上传 pdf 文件 文件发送至
  • MySQL - 组内计数器

    我想根据升序变量为组中的每一行添加一个计数器 我有一个解决方案 但如果组内的某些变量相等 它就不起作用 CREATE TABLE tb g CHAR 1 x INTEGER INSERT INTO tb g x VALUES a 1 a 2
  • 如何使用JNA回调

    我正在使用 JNA 调用 dll 文件的函数 简单DLL h typedef int stdcall eventCallback unsigned int id int value namespace test class hotas pu
  • 在 ARM 资源组中运行的 Webrole 云服务

    到目前为止 我对使用 WebRoles 或 Worker Roles 进行 PaaS 部署的理解 旋转Web角色或工作者角色将创建云服务来管理它 然而 在ARM资源组中 他们没有云服务的概念 那么在ARM资源组中如何管理Web和Worker
  • 如何更改 Microsoft.AspNet.Identity.EntityFramework.IdentityUser 中的 id 类型

    ASP NET MVC 5 EF6 VS2013 我正在想办法将 Id 字段的类型从 string 更改为 int在类型中 Microsoft AspNet Identity EntityFramework IdentityUser 以便让