11
votes

I'm currently having existing membership implemented in ASP.NET 4.5 web forms project. The application uses EntityFramework 6.1.3 version with DbContext and currently in Database first approach. I want to migrate the old membership to use the new ASP.NET identity 2.0 system.

I have followed this article for performing the migration but never succeeded. I got the errors as mentioned in The property 'Claims' on type 'AspNetUser' is not a navigation property.

It confirms that I'm missing something basic in the migration process.

Can someone provide me the step by step guide to perform the success migration?

I want to address the following points:

1) In identity, I have some extra user data other than what default identity is providing. I see there is a IdentityContext which does these identity operations. I have a different context which inherits from DbContext. Do I need to use both the contexts? In other words IdentityContext is compulsory for identity operation? Cannot these two contexts be merged into one?

2) I'm not restricted to Database first approach. Since the identity uses the code first approach I am okay to go ahead with the code-first approach but needs the correct steps to follow up.

3) Since I have extra user data so I need to extend the IdentityUser to add new properties? If I will extend the IdentityUser will the identity code work seamlessly?

4) I followed https://www.youtube.com/watch?v=blmkPA7XQf8 video tutorial which adds the migration in the ApplicationDbContext. The ApplicationDbContext inherits IdentityContext. It worked for me but I want to add migration for my own context which inherits from DbContext. It's because the ApplicationDbContext doesn't include the other tables(non-identity tables).

5) I tried applying the migration in my custom Context.cs file which contains all the identity and non-identity tables. I created this class using the reverse engineering approach by EntityFramework Power Tools as suggested in this article.

After the POCO classes are created, I added migration and updated the database. The main errors I got are:

IdentityUserLogins: EntityType: EntitySet 'IdentityUserLogins' is based on type 'IdentityUserLogin' that has no keys defined. 

IdentityUserRoles: EntityType: EntitySet 'IdentityUserRoles' is based on type 'IdentityUserRole' that has no keys defined.

As per this solution I added the configuration but ended up with creating new tables for IdentityUserLogin, IdentityRole etc. which are duplicate identity tables.

6) Even if I'm keeping duplicate identity tables (e.g AspNetUserRoles and IdentityUserRole), I'm not able fetch data using the identity code var user = userManager.FindAsync(UserName.Text, Password.Text); and getting exception:

Invalid column name 'UserId'
1
I see that, this is an old post, but, have you seen this tutorial ? Please also take a look at this post.Adil Mammadov

1 Answers

1
votes

1) In identity, I have some extra user data other than what default identity is providing. I see there is a IdentityContext which does these identity operations. I have a different context which inherits from DbContext. Do I need to use both the contexts? In other words IdentityContext is compulsory for identity operation? Cannot these two contexts be merged into one?

Yes, you need to use two context when implements ASP.NET identity with Database first. As Asp.Net identity uses System.Data.SqlClient provider while Edmx uses System.Data.EntityClientprovider.

2) I'm not restricted to Database first approach. Since the identity uses the code first approach I am okay to go ahead with the code-first approach but needs the correct steps to follow up.

It is easy to implement in code first approach even ASP.NET MVC default template provides the implementation of ASp.NET identity with code first approach but not a problem with Database first approach as well. https://danieleagle.com/2014/05/setting-up-asp-net-identity-framework-2-0-with-database-first-vs2013-update-2-spa-template/

3) Since I have extra user data so I need to extend the IdentityUser to add new properties? If I will extend the IdentityUser will the identity code work seamlessly?

Yeah, You can extend it.Whenever you want to extend the properties of User.Identity with any additional properties , add these properties to the ApplicationUser class first like so:

public class ApplicationUser : IdentityUser
    {
        public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser> manager)
        {
            // Note the authenticationType must match the one defined in CookieAuthenticationOptions.AuthenticationType
            var userIdentity = await manager.CreateIdentityAsync(this, DefaultAuthenticationTypes.ApplicationCookie);
            // Add custom user claims here
            return userIdentity;
        }

        //Extended properties
        public string City { get; set; }
    }

These three points also resolve remaining points as well.