Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is Asp.Net Identity IdentityDbContext a Black-Box?

There is a lot of confusion it seems around IdentityDbContext.

If we create two Database Contexts in our application, one for Identity and one for our custom business data, the Identity Database Context inherits from IdentityDbContext while our custom business data inherits from DbContext.

So let's add the following to a controller:

private MyDbContext db = new MyDbContext(); private ApplicationDbContext identityDb = new ApplicationDbContext(); 

And the following to an Index method in the controller:

var thingsInMyBusinessDb = db.Things.ToList(); var usersInIndentityDb = identityDb.AspNetUsers.ToList(); // THIS WILL HAVE AN ERROR var roles = identityDb.AspNetRoles.ToList(); // ERROR 

You will also notice that the tables in the Indentity Database are not available. Why is this?

Currently as of 2.0.0-beta1 there is a Users and Roles items, but I would have expected the actual tables to be available. And why not? What if I wanted to get to AspNetUserRoles

Sure seems that a lot of confusion and issues with Asp.Net Identity would go away if it were treated like any database context in Entity Framework.

like image 243
Sean Newcome Avatar asked Feb 28 '14 20:02

Sean Newcome


People also ask

Why would you use ASP NET identity?

The ASP.NET Identity is a fresh look at what the membership system should be when you are building modern applications for the web, phone or tablet. ASP.NET Identity allows you to add customized login/logout functionality and customized profile features that make it easy to customize the data about the logged-in user.

How does identity work in asp net?

ASP.NET Core Identity is a membership system which allows you to add login functionality to your application. Users can create an account and login with a user name and password or they can use an external login providers such as Facebook, Google, Microsoft Account, Twitter and more.


2 Answers

The ApplicationDbContext's Users and Roles properties are mapped to the AspNetUsers and AspNetRoles tables, and the rest of the entities (Claims, Logins, UserRoles) are mapped automatically via navigation properties. As far as I know, the prefixing of table names with "AspNet" are the only custom mappings in ApplicationDbContext, everything else is just Entity Framework Code First conventions.

If you need direct access to the tables via the ApplicationDbContext, you can do so like this...

using (var context = new ApplicationDbContext()) {     var users = context.Users.Include(u => u.Claims)                              .Include(u => u.Logins)                              .Include(u => u.Roles)                              .ToList();      var roles = context.Roles.ToList(); } 

You can access a user's roles, claims, and logins via navigation properties on the IdentityUser entity (from the Users DbSet). If you want to query them directly, add them explicitly as DbSets on the context...

public class ApplicationDbContext : IdentityDbContext<ApplicationUser> {     public ApplicationDbContext()         : base("DefaultConnection")     {     }      public DbSet<IdentityUserRole> UserRoles { get; set; }     public DbSet<IdentityUserClaim> Claims { get; set; }     public DbSet<IdentityUserLogin> Logins { get; set; }  } 

And query them like this...

var claims = context.Claims.ToList(); var userRoles = context.UserRoles.ToList(); var logins = context.Logins.ToList(); 

ASP.NET Identity 2.0 exposes Users and Roles IQueryables on the Manager classes for convenience, but it doesn't provide any added functionality over what was available from the DbContext.

like image 116
Anthony Chu Avatar answered Sep 20 '22 00:09

Anthony Chu


There's a fundamental misunderstanding here about how DbContext works. The property names of your DbSets in your context do not correspond to table names. If anything, the table name is based on the class name of the actual entity, but even that can be overridden. A perfect example is of course your user class, which is by default ApplicationUser, but will reside in a table called AspNetUsers.

All the DbSet properties in your context determine is the API you use to access data via Entity Framework. IdentityDbContext implements DbSet properties name Users, Roles, etc. So that is how you access that data, not via the table name (i.e. context.Users).

Further, if you're unhappy with having two contexts, you don't have to keep them as two. Just make your main context inherit from IdentityDbContext<ApplicationUser> instead of DbContext and kill the scaffolded version.

like image 23
Chris Pratt Avatar answered Sep 21 '22 00:09

Chris Pratt