新的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表,您必须实现从IdentityRole
inheritance的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())))