Friday, 8 January 2016

Customize User's Profile in ASP.NET Identity System with EF Database First approach

Introduction
The new ASP.NET Identity system is the preferred way to handle user authentication in ASP.NET applications, whether based on Web Forms or MVC. 
If you want to user database first approach with ASP.NET identity, you need to create two projects - One for getting the ASP.NET Identity tables and second, for integrating with your existing database and add User Profile data. 
Using this method, you can add User Profile data in a separate UserProfile  table (here we have taken Users table) along with AspNetUsers table, while registering a new user.

Getting the Asp.Identity Tables
  • Create an MVC Project with Authentication Individual User Account
  • Create a new test database in MS SQL Server. Open Sql Server → connect to server → Right Click on Databases folder → New Database → Database Name: TestDatabase → click ok.
  • In  Web.Config file change connectionstring named DefaultConnection and change initial catalog as your test database.
  • Run project and register a new user. This will create new tables in your test database.
  • Five Tables will be created AspNetRoles, AspNetUserClaims, AspNetUserLogins, AspNetUserRoles, AspNetUsers
  • Open test database and create scripts of all the tables. To create scripts in SQL server expand databases folder → Expand your TestDatabase  → Expand Tables → Right click on a table → Script Table as → CREATE To → File → Select location where you want to save files → give File name: → Click on save. Do it for all the five tables.
Integrating with your existing DataBase
  • Insert the scripted tables into existing database in SQL Server Management Studio.
  • Run these scripts in this order – AspNetRoles, AspNetUsers, AspNetUserRoles, AspNetUserLogins, AspNetUserClaims - in your existing project database (for ex. XYZDatabase)
  • Create relationship (Primary Key-Foreign Key) with your user table.
  • Relationship among tables is shown in the following diagram.

Add User Profile information in your database while registering a new user
  • Create new Web Project → MVC .
  • Create an EDMX file. To create, Right Click on the folder where you want to keep your edmx file → Add → New Item → In left panel click on Data → Select ADO.NET Entity Data Model → Give Name → Add → EF Designer from Database → Next → New Connection → Provide Server Name, Credentials for Authentication and select database name → Test Connection → Ok → It will create a connection string automatically  → Select “Yes, include sensitive data in the connection string” → Check “Save connection settings in App.Config as” → Set Name → Next → Select table to want to add → Finish.
  • It will create an edmx file. When you expand it, you will see your class files under modelname.tt.
  • In my project, edmx file is  in a separate data layer. Hence, It will create a connection string in App.Config file (later on you have to move the connection string to web.config file.). If your edmx file is in the same project, connection string will be created in web.config file. The connection string will be like this:
  • Now in  web.config file there should be two connection strings – one with provider name “System.Data.SqlClient” and another with provider name “System.Data.EntityClient” as shown below: 
  • In IdentityModels.cs file under Models, Change class name ApplicationUser to UserProfile  and change the ApplicationDbContext like this:

  • In AspNetUserLogin.cs file (under MyModel.edmx → MyModel.tt) add Key attribute as shown below:

  • In AccountController Register() method add User Profile data by creating an object “user” of UserProfile  and pass “user” in CreateAsync method.
  • Replace all the instances of  "ApplicationUser" to "UserProfile".

  • Now run your application and register a new user. You will see a newly registered user’s data will be stored in two tables AspNetUsers and Users.

17 comments:

  1. Why we are creating new table ? Is any restriction to modifiy or add new fields in that table? why not we use current table of AspNetUsers ? Please help me understand it. Once data tables created in our database than why dependency ?

    ReplyDelete
    Replies
    1. I might be a little late but we need new tables because code first approach creates those tables in the localdb whereas we don't normally create databases there.

      Delete
  2. Good POST ( unique ) but some details required like new table datatype and why not we use current tables ?

    ReplyDelete
  3. Unable to determine the principal end of an association between the types 'XXXX.Models.AspNetUser' and 'XXX.Models.UserInfo'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

    ReplyDelete
    Replies
    1. Pls let me know if you were able to solve this hurdle ?

      Delete
  4. hi Rida,
    I was doing the tutorial, but I had a problem in the accountController
    "public async Task Register(RegisterViewModel model)
    {
    if (ModelState.IsValid)
    {
    var user = new User { UserName = model.Email };
    var result = await UserManager.CreateAsync(user, model.Password);"
    here there is an error in var result, when you put the mouse over the parameter user, it says, can not convert from user to applicationuser..any idea?

    ReplyDelete
    Replies
    1. See the last image on this post. You need to create it like this

      var user = new UserProfile{....}

      The reason is that 'UserProfile' is the Identity Model/Entity that is used for storing your users' information.

      Delete
    2. thanks for your fast answer!
      look, I am using visual studio 2015..and still having the error
      can not convert from db.model.userprofiles to applicationuser.
      Do you have the project uploaded to git or something?thanks a lot

      Delete
    3. Your welcome!
      This is not my code so I can't really upload it to git. But you can upload yours and I can take a look at it.

      Delete
  5. Pls this isn't clear to me, at what point are those 5 tables created, what's going to be the column names of those tables. Pls explain

    ReplyDelete
    Replies
    1. The application will create all the necessary Identity Framework tables automatically upon registering a new user. You just need to create scripts of these tables and execute them in your existing Database.

      Delete
  6. Hello,
    Thanks for this post.
    Sorry but I don't seem to find the User class in this line :
    public virtual User User {get; set;}.

    ReplyDelete
    Replies
    1. I'm encountering the same issue above as Abdelhamid Lz. I don't have a User class to reference in my project.

      Delete
    2. Hi,
      User class is mapped with the Users table. When you import all the tables while generating an edmx, this class will be created automatically.

      Delete
  7. This blog gives very important info about .Net Thanks for sharing
    Dot Net Online Course Bangalore

    ReplyDelete