I am currently working on a ASP.Net 5 / ASP.Net MVC 6 application. I am using EntityFramework 7 as ORM framework, and the Code-first approach.
In my model, I have the following:
An AppUser class, which inherits from IdentityUser<int>. IdentityUser is provided through Microsoft.AspNet.Identity.EntityFramework package, and allows one to inherit from the provided class, by specifying the data type from primary keys, and, of course, add custom fields to it. Everything is working fine with it (database schema, inserts, ...)
A Person class, which inherits from the previous, and adds some app-specific fields and logic. Basically, my idea is that every Person in my app is a potential user, but not every user needs to be a Person.
For all my model objects, I implemented a generic repository approach, which basically implements generic CRUD operations for every model class, and allows one to override generic methods for specific domain classes.
But for the AppUser class, ASP.Net Identity framework comes with its own repository, which basically allows one to add a user, add roles to user, checks unicity of logins, etc...
My question is : how can I use these two repositories together, so that when I add a Person, it creates a AppUser through the Identity framework repository, and then stores the field of my custom Person within the same database record ?
Notice that inheritence of Person on AppUser has been resolved by code-first as single table inheritance : the same table stores AppUser and Persons, and a discriminant field was generated.
You create a custom manager class which extends the usermanger class provided by Identity framework. This new CustomUserManager class will have all the functions of UserManager class, plus the new ones which you want to implement for adding a Person
Related
My solution is based on Clean Architecture.
The Domain project should be completely ignorant about the Infrasctrure layer.
The Infrastructure contains a Data Project and an Identity Project.
The Data Project is supposed to implement my repositories. It contains a class called ApplicationDbContext that inherits from DbContext;
The Identity Project is supposed to implement the AspNet Core Identity and all its needs. It contains a class called PortalUser that inherits from IdentityUser and also contains a class called ApplicationIdentityDbContext that inherits from IdentityDbContext;
In the Domain, I have an Entity called User.
User is referenced by several other Entities, like Company (A company has several users).
I'd like to have only one table for both my entities User and the PortalUser.
When I try to apply the migrations, I have several problems referencing User.
What I tried so far:
Create an owned Property called User in PortalUser. But I can't map User in Company entity to an Owned Entity;
Map both User and Portal User to the same table called User, using different DbContexts. But when I apply the migrations to the Database, the migration fails and says that "A table User already exists";
Implement all properties from User in the PortalUser. But when adding a migration it fails and says that other entities like Company can't refer to User.
Make ApplicationDbUser inherit from ApplicationIdentityDbUser but two problems: 1st, it's conceptually wrong to the Clean Architecture; 2nd, The same issues related to having only the PortalUser being created and all other entities referencing User.
I'm stuck on this problem and the project is not going far. All examples that I found so far are raw and don't show what happens when I have navigation properties referencing the User.
The better solution I could think of so far is to have two different tables, one for Identity and another for user needs and references. However, I'm migrating this solution from a messy solution to a more well-organized one, using Clean Architecture. The old version uses only one table for both situations and I can't have a new table and migrate the data.
PLEASE, anyone knows how to solve this problem?
I have divided my ASP.NET MVC 5 project into two distinct projects/assemblies:
MyProject.Entities
and
MyProject.Web
Where .Entities contains my business/domain logic (basically model classes for my custom data objects) and .Web contains the actual ASP.NET MVC framework and web infrastructure.
I am basing this design off of Scott Allen's excellent ASP.NET MVC 5 Fundamentals course where he explains how it separates the business logic from the web infrastructure.
However I've run into a problem which Scott only briefly addresses: accessing ApplicationUser in my .Entities classes.
I want my data entity's table to contain a foreign key pointing to a specific ApplicationUser for each entry. But because ApplicationUser inherits from IdentityUser, I would need a reference to AspNet.Identity.EntityFramework.
Scott says that "isn't going to work for a lot of people", and is "rather distasteful". He says that I would have to implement my own UserStore or UserManager to utilize it.
I believe that is vastly overkill for simply wanting to be able to foreign key ApplicationUser in a few tables.
I can get the foreign key column in question into my data table by creating a navigational property in the ApplicationUser class in IdentityModel like so:
using MyProject.Entities;
public class ApplicationUser : IdentityUser
{
public virtual ICollection<Request> Requests { get; set; }
}
and then doing a simple Entity Framework migration. However, I can't explicitly access the user through my object.
So:
Why would it be "distasteful" to reference Entity Framework in my business/domain layer, and
How can I get a foreign key reference declared in that layer to ApplicationUser where I need it?
My application (built in MVC5/EF6) needs to use a single database with two schemas:
identity: To store all the AspNet identity tables for users and roles.
application: To store all my general application tables.
I want to use a separate DbContext for each schema, with the identity one being created with the Microsoft.AspNet.Identity.EntityFramework.IdentityDbContext<ApplicationUser> helper class, and the main application one being created in code with code first. The reason for having two DbContexts like this is so I can put the main application context in a separate assembly and use it in other related projects without having to reference Asp.Net.
However, I want to reference a table in the application schema/context with a foreign key that I want to add to the identity.AspNetUsers table, along with some other extra fields. I then want to create a Users entity in the main context that maps to the identity.AspNetUsers table.
For example, I want an application.Tenants table of which identity.AspNetUsers has a foreign key to, so that I can have many users belonging to a single tenant.
All this is fine I think and will work with no problems, except when it comes to creating the database, and possibly any migrations that affect that table, as I'll have two DbContext's trying to create the same table.
Can I mark a table within OnModelCreating as "do not create", and if so how do I add the foreign key constraint? If not then how do I handle this? I don't think what I'm trying to do is unreasonable. I just want to avoid having two "Users" tables linked with an implied foreign key (i.e. with no actual foreign key constraint).
Why exactly do you want to use two separate DbContexts? It would be easier to have a single context for both ASP.NET identity data and your business entities:
public class DatabaseContext : IdentityDbContext<UserInfo>
{
public virtual DbSet<Entity> Entities { get; set; } // Your business entities
public DatabaseContext()
: base("name=DatabaseContext")
{
}
}
Notice that the DatabaseContext inherits from the IdentityDbContext<UserInfo>.
There are some trade-offs with this approach: for example, your data access layer should reference Microsoft.AspNet.Identity.Core and Microsoft.AspNet.Identity.EntityFramework; however, having a single database context in your project makes things much easier if you are using dependency injection or Entity Framework migrations.
I have a PHP/MySQL-system that I'm porting to ASP.NET MVC5 with Azure SQL. I have a problem with grasping the concept of the new Identity solution that Microsoft has introduced. Becuase the database structure exists from the previous system, I have transfered the old MySQL database to Azure SQL. So far so good. There I have a user table with all user related data, such as username, email password etc. Becuase I wanted to continue using this table, I created the extra database fields that exists in the Identity user table. I have also created custom UserManager and other classes (MyUser, MyClaim etc.) so I am able to log in. Everything works.
Since I have a database first approach, not a code first approach, I wanted to use the User class to interact with the user table. But my UserManager returns the MyUser class (that inherits from IdentityUser), not the User class in my model. Even my dbcontext returns the MyUser class when I ask for the all the users in the User table.
Do I really need to manually update the MyUser class to replicate the User table, so if I do a change in the User table and updates my model, I have to manually update the MyUser class because the system can't/woun't use the models user class?
IdentityUser represents a default EntityFramework IUser implementation. Since you have your own existing schema, you're going to have to hand roll some classes to implement ASP.NET Identity to use your own tables.
In order to use your User class with ASP.NET Identity, you'll need to make sure it inherits from Microsoft.AspNet.Identity.IUser. After implementing IUser, update all references to MyUser with a reference to your User class. Note: You'll probably want to update your User class to something like MyAppNameUser for clarity.
After doing the above, you'll probably need to implement IUserStore so that the UserManager class can interact with your database schema.
You may want to take a look at https://github.com/raquelsa/AspNet.Identity.MySQL to get some ideas on implementing some of the ASP.NET Identity interfaces.
I've just started working on an existing codebase. It's an AngularJS frontend with a WebAPI backend. It's currently using Microsoft.AspNet.Identity.EntityFramework 2.1.0 and Microsoft.AspNet.Identity.Owin 2.1.0 with code first EntityFramework 6.1.1
The problem I'm having is that the codebase currently uses two database contexts, and these contexts both map to a single underlying table.
The first dbcontext is used only to support ASP.Net Identity;
public class AccountSecurityDBContext : IdentityDbContext<AccountUser, AccountRole, Guid, AccountUserLogin, AccountUserRole, AccountUserClaim>
{
...
modelBuilder.Entity<AccountUser>().ToTable("User");
...
}
where AccountUser must derive from IdentityUser due to ASP.Net Identity.requirements;
public class AccountUser : IdentityUser<Guid, AccountUserLogin, AccountUserRole, AccountUserClaim>
{
...
}
This AccountUser class is purely used to satisfy ASP.Net Identity. The the second DbContext has another mapping to the User table, used for everything other than authentication.
public class MainContextUnitOfWork : DbContext
{
...
modelBuilder.Entity<User>().ToTable("User");
...
}
So, currently, there are two classes, AccountUser and User both mapping to the same underlying User table.
This use of two DbContexts each with their own mapping to the same underlying table is causing problems. EntityFramework wants to create two migrations, one per DbContext resulting in the generation of duplicate migrations. I am aware of the add-migration --ignore option so that we can generate an empty migration for the second DbContext and that empty migration will generate a new hash of the data model in the empty migrations's designer.cs file.
Ideally I feel we should really only be using one DbContext as it's rather confusing having two DbContexts where we're using one of the DbContexts purely to support ASP.Net Identity. However I can't see how to easily refactor due to the fact that to use ASP.Net Identity the user entity must derive from IdentityUser. It's not acceptable for us to have an Entity deriving from IdentityUser to be passed up to higher layers in the appplication as this would introduce a dependency on EntityFramework in those higher layers.
My current feeling is that use of ASP.Net Identity is causing more problems than it's solving and that we'd be better off implementing our own authentication mechanism.
To reiterate. The problem lies in the fact that ASP.Net Identity forces inheritance from IdentityUser rather than allowing, for example, an implementation based on a (non-existent) IIdentityUser interface.
I've been unable to find any examples of how to overcome this.
So, the question is; Has anyone successfully used ASP.Net Identity 2.1.0 with EntityFramework 6.1.1 where you've been able to both accommodate the ASP.Net Identity requirements of using a class derived from IdentityUser and to pass a User entity up to application layers without having to reference EntityFramework in those higher layers.
Thanks in advance for any insights.
The answer turned out to be pretty simple. Although we are using EntityFramework and Asp.Net Identity, we didn't actually want to use Microsoft.AspNet.Identity.EntityFramework.
What we needed to do was just use Microsoft.AspNet.Identity and implement our own user and role store.