使用mvc5身份

时间:2017-04-07 12:20:32

标签: c# asp.net-mvc asp.net-identity

我正在开发一个MVC项目,该项目需要使用Identity创建的身份验证和授权,我的项目数据库还包括应该使用该系统的主要实体,处理这种情况的最佳实践是什么。

  1. 我应该根据我的要求自定义身份ApplicationUser。
  2. 创建我自己的表(模型)并将它们与身份表集成,我不知道如何做到这一点。 或任何其他解决方案。

1 个答案:

答案 0 :(得分:1)

您当然应该自定义Identity实体,因为这是创建Identity的全部原因:允许更大的可扩展性。要拥有不同类型的"用户",您应该继承ApplicationUser;重要的是,{em>不直接来自IdentityUser。这将确保核心身份关系(角色,声明,登录等)都与单个用户"表,然后您可以扩展该表或创建其他表来保存其他用户数据。

public class ApplicationUser : IdentityUser

public class Student : ApplicationUser

public class Instructor : ApplicationUser

默认情况下,此继承将由TPH(每个层次表)实现,也称为STI(单表继承)。这意味着所有派生类的所有属性都将由单个数据库表上的列表示。还会添加Discriminator列,其中包含已保存的实际类的名称,即" ApplicationUser","学生"或"讲师& #34 ;.当您从查询中构建对象图时,EF将使用此列来实例化正确的" user"类型。

这种方法有利有弊。由于所有内容都存在于单个表中,因此查询简单快捷。但是,此方法必须使每个派生类的所有属性必须在数据库级别上为可空。显而易见的原因是,如果Instructor有必填列,则无法保存Student,因为Student不具备满足该要求的属性。您仍然可以使用视图模型强制在视图级别需要这些属性。但是,数据库中的实际列必须是可为空的。

另一种方法是使用名为TPT(Table Per Type)的内容。在此继承策略中,将为具有所有公共属性的基类(ApplicationUser)创建一个表。然后,将为每个谨慎的派生类创建一个表,只包含该类中存在的属性。外键将添加到基类的表中,然后EF将用于将该表中的公共数据连接到派生类的特定数据。表。这种方法允许您在数据库级别强制执行NOT NULL,但它当然需要连接来引入所有数据,这会降低查询速度。

要实现TPT,您只需要将[Table]注释添加到派生类中:

[Table("Students")]
public class Student : ApplicationUser

[Table("Instructors")]
public class Instructor : ApplicationUser

最后要注意的是,您需要如何使用UserManager。如果你搭建了AccountController,你会注意到它设置了一个UserManager控制器属性,然后用它来创建用户,查找用户,更改密码等。这实际上是一个实例UserManager<ApplicationUser>的{​​{1}},因为它是一种通用类型。如果您需要专门使用StudentInstructor,则需要分别实例化UserManager<Student>UserManager<Instructor>。您无法使用UserManager<ApplicationUser>的实例,因为它会将您的派生类型转发为ApplicationUser。例如:

var student = new Student { ... };
await UserManager.CreateAsync(student);

实际上会导致ApplicationUser保存到数据库中。特定于学生的数据将被丢弃,Discriminator列的值将为&#34; ApplicationUser&#34;。