Customize User's Profile in ASP.NET Identity System

Note: You should read this post instead, I found below walkthrough will not work on ASP.NET Identity 2. I will re-work on this post soon.

In this post you will learn how to customize User’s Profile and add some more fields like FirstName, LastName, EmailID etc with ASP.NET Identity System. In my last post I listed some of the great new features introduced with Identity system.

We are going to learn following things:

The demo I’m going to use will be on MVC but with other frameworks like Web Forms it will be exactly same.

Introduction

ASP.NET Identity System is a new Membership system for building ‘One ASP.NET’ applications. It allow us to add login features to our application and makes it really easy like never before to customize data about the logged in user, this is what we are going to learn in this post.

With Simple Membership it was a tough task to add other information while registering new user. Also, it was not possible to do some of the important task like database migrations, seeding user profile information’s etc etc. But now with this brand new ASP.NET Identity System, things are easier.

You can learn more about all the new features here.

Simple Membership and ASP.NET Identity System

Here I would like to show the table structure of Simple Membership and the new one ASP.NET Identity. We can see, there is a table ‘_MigrationHistory’ this helps Entity Framework Code First in migrating the database. We can also see few new tables got added, this will be used to manage other social login methods, and we will explore it later.



Customizing User’s Profile to add new fields in same database table

What about adding user’s First Name, Last Name and Email ID, while creating new user account in the application? It was really difficult before to add these extra information while registering new user. Now, with ASP.NET Identity System, it is easy to add extra information about the user.

Let’s follow the steps from here.

Step 1: Getting Ready

With Visual Studio 2013, these bits are already included with templates but in case if we want to migrate our existing application then we can download the bits from NuGet. Also note, with Visual Studio 2013 RC or RTM, we need to update packages given below.

We need to install these two packages:-

Microsoft.Aspnet.Identity.Core
This package contains the core interfaces of ASP.NET Identity.

Microsoft.Aspnet.Identity.EntityFramework
This package contains the implementation of ASP.NET Identity System which works with Entity Framework Code First. This means that if we use this package then we can store information in a SQL Server database. Also we can easily plug other databases if we wanted.

I had a bad experience on this because I were using RTM version of Visual Studio 2013, here is the error I was getting:

Mapping and metadata information could not be found for EntityType 'ProfileManagementMVC.Models.ApplicationUser'.

Then I updated my IDE and problem got solved. Alternatively, while creating new project we can update NuGet packages before proceeding, and it will also work.

Step 2: Create Project

Open Visual Studio 2013 and create a new ASP.NET Web Application from File | New | Project | .NET Framework 4.5 | ASP.NET Web Application by selecting MVC as a project template.

Step 3: Looking at Register Page

Run the application and navigate to register page. Assume how about adding First Name, Last Name and Email ID fields on this page? This can be done very easily now.


Step 4: Enable Entity Framework Code First Database Migrations

ASP.NET Identity System uses Entity Framework Code First approach to generate database tables. We are going to change the default schema of the database by adding new properties in code first model class that needs database migration to generate database tables. Also, if we use database migration then older database records will stay as it is in the database tables. I have recorded following videos and uploaded on YouTube on Code First Database Migrations, just watch it.


For this, I am going to execute following two commands from ‘Package Manager Console’, the NuGet power tool.

Just execute the command “Enable-Migrations”, as given below.


Once we enabled the database migrations, we can go ahead and add new properties First Name, Last Name and Email ID.

Step 5: Add new properties

Let’s add new properties First Name, Last Name and Email ID in Models | IdentityModels.cs file, as given below.

public class ApplicationUser : IdentityUser
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string EmailID { get; set; }
}

Step 6: Add New Migration

Once we added the properties, bring the Package Manager Console and execute following command.

Add-Migration "NameEmailID"

This command will generate a big blog database script file, now execute following command to run this script file against database.

Update-Database

Now, all the new properties will turn into table fields in the same database table. We could generate new table also, we will explore this in next blog post.



Step 7: Update RegisterViewModel

Once we updated the database table, we can go and update the AccountViewModel.cs RegisterViewModel, we can find it inside Model folder.

public class RegisterViewModel
{
    [Required]
    [Display(Name = "Frist Name")]
    public string FirstName { get; set; }

    [Required]
    [Display(Name = "Last Name")]
    public string LastName { get; set; }

    [Required]
    [Display(Name = "Email ID")]
    [EmailAddress]
    public string EmailID { get; set; }

    [Required]
    [Display(Name = "User name")]
    public string UserName { get; set; }

    [Required]
    [StringLength(100, ErrorMessage = "The {0} must be at least {2} characters long.", MinimumLength = 6)]
    [DataType(DataType.Password)]
    [Display(Name = "Password")]
    public string Password { get; set; }

    [DataType(DataType.Password)]
    [Display(Name = "Confirm password")]
    [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
    public string ConfirmPassword { get; set; }
}

I highlighted newly added codes above.

Step 8: Update Register View Page

Once we have the ViewModel ready, we are good to update its view page “Register” which can be found in View | Account | Register.cshtml.

<div class="form-group">
    @Html.LabelFor(m => m.FirstName, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.TextBoxFor(m => m.FirstName, new { @class = "form-control" })
    </div>
</div>
<div class="form-group">
    @Html.LabelFor(m => m.LastName, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.TextBoxFor(m => m.LastName, new { @class = "form-control" })
    </div>
</div>
<div class="form-group">
    @Html.LabelFor(m => m.EmailID, new { @class = "col-md-2 control-label" })
    <div class="col-md-10">
        @Html.TextBoxFor(m => m.EmailID, new { @class = "form-control" })
    </div>
</div>

Step 9: Update Account Controller’s Register action (Post Version)

Now one thing left is updating Post Version of Register action. Here I am using ApplicationUser() to map the properties with appropriate model.

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Register(RegisterViewModel model)
{
    if (ModelState.IsValid)
    {
        var user = new ApplicationUser() { UserName = model.UserName, FirstName = model.FirstName, LastName = model.LastName, EmailID = model.EmailID };

        var result = await IdentityManager.Users.CreateLocalUserAsync(user, model.Password);
        if (result.Success)
        {
            await IdentityManager.Authentication.SignInAsync(AuthenticationManager, user.Id, isPersistent: false);
            return RedirectToAction("Index", "Home");
        }
        else
        {
            AddErrors(result);
        }
    }

    // If we got this far, something failed, redisplay form
    return View(model);
}

I highlighted newly added codes above.

Step 10: Run Application

Let’s go and run the application and try to create new user account. Look at the image given below, I success to login and I can see all the data (FirstName, LastName, EmailID) up in the database.





Step 11: Accessing User Profile Data

If user is logged in, we can access user’s profile information that we just added following way in the controller.


Or if we want to access these information directly on the view page, here is another way.

@using Microsoft.AspNet.Identity;
@using Microsoft.AspNet.Identity.EntityFramework;
@using ProfileManagement.Models;

<div>
    @{
        if (Request.IsAuthenticated)
        {
            var manager = new UserManager<ApplicationUser>(new UserStore<ApplicationUser>(new ApplicationDbContext()));
            var currentUser = manager.FindById(User.Identity.GetUserId());
            <p>@currentUser.EmailID</p>
            <p>@currentUser.FirstName @currentUser.LastName</p>
        }
    }

</div>

Please note I have used all the required namespaces.


Hope this helps.
Thanks.

Comments

  1. Thanks for the tutorial,

    You mentionned that "The demo I’m going to use will be on MVC but with other frameworks like Web Forms it will be exactly same."

    Could you, or anybody else, explain how to use this solution in Web Forms. I have no clue how to do it as there are no Controllers.

    Cheers

    ReplyDelete
  2. For those who trying to achieve this in Web Forms.

    As you know MVC as well as Web Forms uses same 'ASP.NET Identity System' architecture. In this article I talked about MVC way, if you want to achieve this in Web Forms, this comment is for you.

    Open IdentityModels.cs class, inside that there will be a class ApplicationUser inherits IdentityUser. Here you can add your additional fields/properties. Same set of controls you need to place on Register.aspx form. Now inside Register.aspx.cs file, update var user = new ApplicationUser() { UserName = UserName.Text }; exactly the way i suggested in the article. Do not forget to update the database to match it.

    I don't have sample code to show you now but things are always same in MVC and Web Forms as it uses same Identity model... if you try. Hope this helps.

    If you still face any issue join our FB group https://www.facebook.com/groups/learnmvc/ and ask the questions with detailed description if possible screenshots.

    ReplyDelete
  3. Hi Kumar

    Nice article and very well explained

    ReplyDelete
  4. Hi Abhimanyu,
    Nice article. One ASP.NET Identity is quite easier than the earlier providers. However, I would like to know if it is a good approach to store profile specific info (such as, first name, last name, gender, birthdate, marital status, and many other personal info in AspNetUser table? I think that would make it cumbersome. Is there any other approach to keep user info and profile info separate from each other?

    ReplyDelete
  5. Hi Abhimanyu thank you for fantastic article it hepled me alot. Dear Abhimanyu how can i create more than one tables for users like Students, Teachers, Parents etc and link that tables AspnetUser. I have consumed lot of hours but unable to do this. Thanks in advance.

    ReplyDelete
  6. Hi, thanks and very helpful article, I am facing a small issue to get user profile details in my partial view as I am using separate entity for User Profile. for any help thanks in advance.

    I have posted the issue in https://stackoverflow.com/questions/23709758/mvc-identity-user-profile-extension-and-accessing-properties-and-methods

    ReplyDelete
  7. Hi, Thanks and very nice article, I am facing a small issue while accessing user profile details , details are posted under
    https://stackoverflow.com/questions/23709758/mvc-identity-user-profile-extension-and-accessing-properties-and-methods
    thanks in advance for any help.

    ReplyDelete
  8. Great tutorial, Thanks man

    ReplyDelete
  9. Hi, Thanks for the guide, do you have a tutorial on "how to store user profile information in a different table"?

    ReplyDelete
  10. Very nice tutorial, i wanted to ask one thing "Add-Migration "NameEmailID" what happens with this command? could you please explain...thanks

    ReplyDelete
  11. thanks so much for your tutorial!!
    and i have a question...!

    How can i get value "Email" and "Password" according a username(table aspnetusers)??

    i means... have some function easy for use??

    like:
    string email=getEmail(username);
    string password=getPassword(username);

    thanks!!!

    ReplyDelete
  12. How to know which user last login and date time in MVC, if anyone have code then please share .

    ReplyDelete
  13. how we do this : Last login user date time fucntionality in MVC

    ReplyDelete
  14. Can you please share with us the code and how you can accomplish the above when using Web Forms?
    There is little documentation focused on Web Forms and this could really help us.
    Thanks

    ReplyDelete
  15. Having issues with web forms. Please help:

    An exception of type 'System.InvalidOperationException' occurred in mscorlib.dll but was not handled in user code

    Additional information: The model backing the 'ApplicationDbContext' context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269).

    ReplyDelete
  16. Hi I am Bhanu
    how to retrieve user profile image from data base after log in completed in asp.net
    please help me out....
    Advance in thanks

    ReplyDelete
  17. var user = new ApplicationUser() { UserName = UserName.Text, FirstName = FirstName.Text, LastName = LastName.Text, BirthDate=BirthDate.Text, Email = Email.Text };

    birthdate.text ... getting error !

    ReplyDelete
  18. UnknownFriday, April 18, 2014 12:31:00 am

    Hi Abhimanyu thank you for fantastic article it hepled me alot. Dear Abhimanyu how can i create more than one tables for users like Students, Teachers, Parents etc and link that tables AspnetUser. I have consumed lot of hours but unable to do this. Thanks in advance.

    ReplyDelete
  19. Hi Abhimanyu thank you so much for this article!

    My problem is that i can't execute the "Enable-Migrations" commande, it puts me the error 0x80070057 (E_INVALARG).

    Does someone have a solution to solve this problem or even to just avoid the "Enable-Migrations" Step? :(

    ReplyDelete
  20. The tutorial is wonderful. I tried the above in web forms and its working but it is not storing the data entered in the AspNetUsers table. Please what can be done?

    ReplyDelete
  21. please kindly send me the code and its database at [email protected]

    ReplyDelete
  22. Hi. Super tutorial. I need some help regarding your tutorial. When a user who has already registered, and wants to update their details, i.e. change their name or email address etc, when a user clicks the "Hello "Name" in order to manage their account, how can they edit all their user details instead of just updating their password?

    ReplyDelete

Post a Comment

Popular posts from this blog

Migrating database from ASP.NET Identity to ASP.NET Core Identity