新的ASP.NET MVC 5应用程序如何知道如何创build数据库以及Account Controller如何访问数据库?

我使用Visual Studio 2013 Update 2创build了一个ASP.NET MVC 5应用程序。 在应用程序中,我有一个帐户控制器。 这与我习惯的不同,不包含dbcontext的实例化。

public class AccountController : Controller { private ApplicationUserManager _userManager; public AccountController() { } public AccountController(ApplicationUserManager userManager) { UserManager = userManager; } public ApplicationUserManager UserManager { get { return _userManager ?? HttpContext.GetOwinContext().GetUserManager<ApplicationUserManager>(); } private set { _userManager = value; } } 

我的默认情况下创build的web.config具有这样的连接string:

  <connectionStrings> <add name="DefaultConnection" connectionString="Data Source=(LocalDb)\v11.0;AttachDbFilename=|DataDirectory|\aspnet-WebApplication3-20140417072624.mdf;Initial Catalog=aspnet-WebApplication3-20140417072624;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> 

有人可以向我解释当第一次启动时,应用程序知道如何为这个应用程序创build一个数据库?

此外,在后续的启动,它使用entity framework来访问身份表进行身份validation?

1)这里有什么:

当您创build一个新的MVC 5应用程序并select“ 个人用户帐户 ”时,将包含一个使用entity framework6 Code-First的新ASP.NET身份提供程序

微软已经采用了EF-Code-First来使Identity成为可定制的。

当首次访问Identity时, Entity Framework会检查数据库是否存在。 除非另行configuration,否则使用"DefaultConnection"来查找身份数据库。 如果在调用标识时数据库不存在, EF会自动创build数据库。

注意你的连接string包含

 `AttachDbFilename=|DataDirectory|\aspnet-WebApplication3-20140417072624.mdf` 

如果你打开你的App_Data文件夹,你应该有一个aspnet-WebApplication3-20140417072624.mdf文件。

如果您双击这个.mdf文件, VS2013服务器资源pipe理器将打开您的数据库。 如果您已经尝试访问任何标识function,您将创build这些表:

  • _MigrationHistory
  • ASPNetRoles
  • ASPNetUserClaims
  • ASPNetUserLogins
  • ASPNetUsers

默认情况下,您的应用程序被configuration为使用SQL Server Compact (MDF文件),因此您不必运行实际的SQL Server实例。 所有这些都是可定制的。 您的MDF文件的名称,标识数据库的模式,selectSQL Compact与实际的SQL Server实例。 更改您的连接string,或者创build一个新的连接并将其传递到您的上下文。


2)我的上下文在哪里?

所有这一切都很好,但是您提出的一个重要问题基本上是“我的上下文在哪里? ”以及与您如何进一步自定义数据库或更改validation逻辑相关的隐含问题。

您会注意到您的项目引用了Microsoft.AspNet.Identity.EntityFramework 。 这个程序集是IdentityDBContext<TUser>UserManager类的实现的一个实现。

打开您的AccountController ,并注意构造函数具有UserManager对象传递,而这又传递了一个new UserStore对象,它传递给一个ApplicationDbContext

  public AccountController() : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()))) 

ApplicationDbContext在您的模型文件夹中定义。 在该文件夹中,您将find一个IdentityModels.cs文件。 打开它,你会看到

 public class ApplicationDbContext : IdentityDbContext<ApplicationUser> { public ApplicationDbContext() : base("DefaultConnection") { } } 

这是您的身份上下文分配的地方。 您可以更改传递给ApplicationDbContext构造函数的连接名称,也可以在帐户控制器中定义和使用不同的上下文。


3)我如何定制我的身份模式?

定义在IdentityModels.cs文件中的另一个类是inheritance自IdentityUser类的ApplicationUser类。

 public class ApplicationUser : IdentityUser { } 

您添加到此类的任何属性都将保留ASPNetUsers表中。 模式的其余部分在IdentityDbContext类中定义。 因此,虽然您可以通过将DBSet添加到上下文定义来将更多的表(例如特权)添加到您的标识架构,

 public DBSet<Privileges> { get; set; } 

改变其他表(angular色,索赔等)也是可能的,但涉及更多。 例如,要自定义Roles表,您必须实现从IdentityRoleinheritance的NewIdentityRole ,并通过覆盖Context的OnModelCreating()方法来添加它的关系。

这篇关于Customizing Roles Tables的文章在描述涉及的步骤方面做得很好。 即使在这里,您也会发现只需添加新的列就会有很大的麻烦。 从IdentityDbContext类中创build的原始模式中删除表或列可能与创build您自己的IdentityDbContext类的实现同样麻烦。

肯定会在ApplicationUserManager ,我的猜测是这是一个服务,利用数据库的上下文,以pipe理应用程序的用户。

您可以右键单击此类,然后单击Go to definition并继续执行,直到您可以看到初始化数据库的类。

另外,在MVC 4中,初始化是在Filter Attribute中完成的。 因此,如果有Filter文件夹,请查看Filter文件夹。 我知道这不是MVC 5.但它仍然可以适用。

正如Melina指出的那样,原来的问题引用了当前的ASP.NET Identity 2.x模型。

Dave Alperovich的答案提供了关于ASP.NET Identity背后概念的宝贵背景信息,尽pipe这些例子是从ASP.NET Identity 1.x中提取的,而这些信息在2014年被取代了。

Callum Linington提供了“教人鱼”的答案。 通过遵循他的build议,很容易看到2.x“ApplicationUserManager”类是从1.x风格的“UserManager”派生的。

答案基本上是当创build“AccountController”时作为参数注入的“ApplicationUserManager”,在其自己的构造函数中连接到身份数据存储:

 var manager = new ApplicationUserManager(new UserStore<ApplicationUser>(context.Get<ApplicationDbContext>())); 

注意这个“隐藏的”2.x代码如何与上面给出的1.x代码非常相似:

 public AccountController() : this(new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext())))