I created an ASP.NET MVC 5 Application using Visual Studio 2013 Update 2. In the application, I have an Account controller. It's different from what I am used to and does not contain an instantiation of 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;
}
}
My web.config
that is created by default has a connection string like this:
<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>
Can someone explain to me how the application knows to create a database for this application when it starts for the first time?
Also, on subsequent starts, does it use Entity Framework to access the Identity tables to do the authentication?
1) WHAT'S GOING ON HERE:
When you create a new MVC 5 application and choose "Individual User Accounts", a new ASP.NET Identity Provider is included which uses Entity Framework 6 Code-First.
Microsoft has adopted EF-Code-First to make Identity as customizable as possible.
When Identity is accessed for the first time, Entity Framework checks to see if the database exists. Unless configured otherwise, it uses the
"DefaultConnection"
to find the identity database. If the database does not exist when Identity is called, EF automatically created the database.Notice your connection string contains
If you open your App_Data Folder, you should have a aspnet-WebApplication3-20140417072624.mdf file.
If you double click on this .mdf file, the VS2013 Server Explorer will open your DB. If you have already attempted to access any Identity functionality, you will these tables created:
By default, your app is configured to use SQL Server Compact (MDF file) so you don't have to have an actual SQL Server Instance running. All of this is customizable. The name of your MDF file, the schema of Identity Database, the choice of SQL Compact vs an actual SQL Server instance. Change your Connection String, or create a new one and pass this new connection to your context.
2) WHERE IS MY CONTEXT?
All this is well and good, but an important question you asked is basically "Where is my context?", and the just as relevant implied questions regarding how you can further customize your DB or alter validation logic.
You will notice that your project references
Microsoft.AspNet.Identity.EntityFramework
. This assembly is an implementation ofIdentityDBContext<TUser>
and implentation ofUserManager
Class.Open your AccountController, and notice the constructor has
UserManager
object passed which in turn has anew UserStore
object passed, which gets passed aApplicationDbContext
.The
ApplicationDbContext
is defined in your Models Folder. Inside that folder, you will find an IdentityModels.cs file. Open it and you will seeThis is where your Identity Context is assigned. you can change the connection name passed to the
ApplicationDbContext
constructor, or define and use a different context in your account controller.3) HOW DO I CUSTOMIZE MY IDENTITY SCHEMA?
Another class defined IN IdentityModels.cs file is the
ApplicationUser
class which inherits fromIdentityUser
class.Any properties you add to this class will be persisted in your ASPNetUsers Table. The rest of the schema is defined in
IdentityDbContext
class. So, while you can add more tables (e.g. Privileges) to your Identity Schema by adding a DBSet to the Context Definition,Altering other tables (Roles, Claims, etc) is also possible, but far more involved. For example, to customize the Roles table, you would have to implement a
NewIdentityRole
inheriting fromIdentityRole
and add it's relationship by overriding theOnModelCreating()
method for your Context.This article on Customizing Roles Tables does a good job of describing the steps involved. Even here, you will find that there is significant trouble invested into simply ADDING new columns. Removing tables or columns from the original schema created in the
IdentityDbContext
class is probably as much trouble as creating your own implementation ofIdentityDbContext
class.As Melina pointed out, the original question referenced the current ASP.NET Identity 2.x model.
Dave Alperovich's answer provided valuable background information on the concepts behind ASP.NET Identity, although the examples were drawn from ASP.NET Identity 1.x, which was replaced in 2014.
Callum Linington provides the "teach a man to fish" answer. By following his advice, it's easy to see that the 2.x "ApplicationUserManager" class is derived from a 1.x-style "UserManager".
The answer is basically that the "ApplicationUserManager", which is injected as a parameter when "AccountController" is created, connects to the identity data store in its own constructor:
Note how this "hidden" 2.x code is very similar to the 1.x code as given above:
Surely it would be in the
ApplicationUserManager
, My guess is that this is a service which utilizes the db context in order to manage the application users.You can right click on this Class and click
Go to definition
and keep doing that until you can see the class which initializes the database.Also, in MVC 4 the initialization is done in a Filter Attribute. So look in the Filter folder if there is one. I know it's not MVC 5. But it could still be applicable.