使用AppplicationDbContext的标识脚手架



ASP.NET Core 2.x现在将标识页和逻辑隐藏在库中。为了用新属性扩展IdentityUser实体,并添加UI和逻辑来处理这些新属性,我们现在可以运行"Identity scaffolder"(在MyProject->add->new scaffolded项下)。不幸的是,这些文档充其量是不完整的,而且在很多情况下,完全是错误的。

我正在努力弄清楚如何与架子工和由此产生的代码进行斗争,以实现我认为相当标准的用例:

  1. 我从一个新的ASP.NET Core MVC应用程序开始
  2. 我想用我自己的属性来扩展IdentityUser。由于这涉及到创建一个继承类,所以我希望新类的名称为ApplicationUser
  3. 我想搭建我需要处理的身份页面(登录、注册、管理等)
  4. 我想使用现有的ApplicationDbContext

我的问题是,在阅读文档和与Identity架子工玩耍时,我不知道如何让架子工让我扩展IdentityUser继续使用现有的ApplicationDbContext

在查看了文档并与架子工和生成的代码进行了比较之后,我想我已经了解了大部分内容。

  1. 从一个新的ASP.NET核心Web应用程序开始,使用"个人用户帐户"身份验证。显然,无论您是从"Web应用程序"(即Razor Pages)还是"Web应用(模型-视图-控制器)"(即MVC)开始,都无关紧要。最终,Identity页面将是Razor页面,但它们在MVC应用程序中的功能很好
  2. 构建解决方案。我不确定这是否有必要,但这并不伤人
  3. 在继续之前,请确保您喜欢您的数据库连接字符串(在appsettings.json中)。在Package Manager控制台中,输入命令更新数据库。这显然更新了ApplicationDbContextModelSnapshot.cs文件,以包含从项目模板获得的初始迁移。如果跳过这一步,那么在添加第一个迁移时,它将包括00000000000000_CreateIdentitySchema.cs中已有的所有迁移步骤。此外,显然需要这一步才能让架子工识别现有的ApplicationDbContext
  4. 右键单击项目并选择添加->新建脚手架项目;选择标识项目类型
  5. 指定现有的_Layout.cshtml并选择要构建脚手架的页面
  6. 在数据上下文类旁边,单击下拉箭头并选择现有的ApplicationDbContext
  7. 单击"添加"按钮以执行脚手架

此时,您的项目已连接到现有的ApplicationDbContextIdentityUser类。现在,您可以扩展IdentityUser并连接Identity页面以使用新的扩展实体:

添加从IdentityUser:继承的新ApplicationUser

public class ApplicationUser : IdentityUser
{
public string Nickname { get; set; }
}

将新的ApplicationUser实体添加到ApplicationDbContext类:

public class ApplicationDbContext : IdentityDbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
: base(options)
{
}
public DbSet<ApplicationUser> AppUsers { get; set; }
}

<IdentityUser>的所有实例替换为<ApplicationUser>。这意味着您将更改startup.cs以调用services.AddDefaultIdentity<ApplicationUser>(),并替换对SigninManagerUserManager的所有引用以指定新的<ApplicationUser>Type参数。

Whew。。。现在,您可以进入Register.cshtml.cs之类的内容,创建(或获取)一个新的ApplicationUser而不是IdentityUser,并且所有管道都将连接到ApplicationUser。例如,Register.cshtml.cs中的代码可能如下所示:

var user = new ApplicationUser {
UserName = Input.Email,
Email = Input.Email,
Nickname = Input.Nickname // New property
};
var result = await _userManager.CreateAsync(user, Input.Password);

通常,在没有Identity的情况下,ApplicationDbContext继承自DbContext

我有四个项目的解决方案。WEBWebAPIDATAENTITIES

我有一个位于DATA中的单个ApplicationDbContext,并已将其修改为继承自IdentityDbContext,例如:

public class ApplicationDbContext : IdentityDbContext<IdentityUser>

现在,ENTITIES是定义模型(POCO)的地方。

并且,DATA中的AppliationDbContext包含对这些类的引用,并包含EF使用的DbSet<T>属性设置器。ENTITIES中的Person(又名ApplicationUser)类如下所示:

public class Person : IdentityUser { [PersonalData] public string LastName { get; set; }

WEB项目中,有了对DATAApplicationDContext的适当引用,我只有一个services.AddDbContext<T>依赖引用;则在CCD_ 47服务添加中使用该上下文

services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDefaultIdentity<IdentityUser>()
.AddEntityFrameworkStores<ApplicationDbContext>();

这似乎达到了只使用一个DbContext服务的目的。它还扩展了AspNetUsers表,以包括我在位于ENTITIES内的POCOPerson模型类中设置的[PersonalData]属性。

现在,自从<IdentityUser>已经扩展,在我的情况下是Person,所有对IdentityUser的引用都应该更新以反映这一点。所以Startup.ConfigureServices现在看起来是这样的:

services.AddDefaultIdentity<Person>()
.AddEntityFrameworkStores<ApplicationDbContext>();

而且,在UI中,为了访问"Person"添加的属性,~/Identity/Account/Manage/Index.cshtml.cs中的引用也需要更新:

private readonly UserManager<Person> _userManager;
private readonly SignInManager<Person> _signInManager;
private readonly IEmailSender _emailSender;
public IndexModel(
UserManager<Person> userManager,
SignInManager<Person> signInManager,
IEmailSender emailSender)
{
_userManager = userManager;
_signInManager = signInManager;
_emailSender = emailSender;
}

您必须更新index.cshtml.cs中的"InputModel"以及OnGetAsync()方法中的"new up"来映射属性——类似于默认设置处理Email的方式。

最后,还有index.cshtml视图文件,用于访问UI/Rarzor显示。

这应该会让你开始你的问题中的项目1-4。

尝试右键单击解决方案,但无法选择ApplicationDbContext。我不得不将Visual Studio更新到最新版本,并安装所有最新的SDK(.Net Core 3.1)。之后,一切都很顺利。希望它能帮助到别人。

相关内容

  • 没有找到相关文章

最新更新