One of the mainline features about ASP.NET Identity is to make it easy to add profile information about the user. In the existing ASP.NET Membership system, User and Profile were separate tables and Profile information about the user was retrieved by using the Profile provider. This made it difficult to customize the Profile information and associate it with the User and application data. ASP.NET Identity makes it really easy to add profile data for your User.

[Update] Adding information on how to store profile information in a different table

[Update] Rick Anderson has a tutorial on asp.net site which also shows how you can add Social Logins to the template as well. Please refer to the tutorial for an entire walkthrough

This post shows how you can customize profile information about the user when you start with the project templates in Visual Studio 2013. Following are the steps to follow to add profile information about the user.

In Visual Studio 2013, create a new ASP.NET MVC application.

You can create a Web Forms application and follow the same steps to add profile information.

Run the application and register a user

You would notice that at the registration screen, the application only asks for a UserName and password. Let’s say that you wanted to add one more field called BirthDate that the users should specify when registering a user.

Enable Entity Framework Migrations

Migrations are recommended to use when you are modifying the schema of the database or you are changing the Code First Model. ASP.NET Identity uses Entity Framework Code First as an underlying framework. For more information on EF migrations please visit http://msdn.microsoft.com/en-us/data/jj591621

Since we have added a new property to the User, we need to update the database to reflect this change. This is where EF migrations is really useful. You can use migrations to update the database schema by doing the following

Goto Package Manager console and do the following

Add-Migration "Birthdate"

This will add a migration file to your project

Update-Database

This command will run all the migration files and update the database schema to add a BirthDate column

Modify the application to add a BirthDate field

The steps here are specific to how you would add a view to MVC, but you can do similar view specific rendering in Web Forms as well

Add BirthDate to RegisterViewModel in Models\AccountViewModels.cs

1: publicclass RegisterViewModel {

2: [Required] [Display(Name = "User name")]

3: publicstring UserName { get; set; }

4:

5: [Required]

6: [StringLength(100, ErrorMessage = "The {0} must be

at least {2} characters long.", MinimumLength = 6)]

7: [DataType(DataType.Password)] [Display(Name = "Password")]

8: publicstring Password { get; set; } [DataType(DataType.Password)]

[Display(Name = "Confirm password")]

9:

10: [Compare("Password", ErrorMessage =

"The password and confirmation password do not match.")]

11: publicstring ConfirmPassword { get; set; }

public DateTime BirthDate { get; set; } }

Add using System; at the top of the class.

Update the Register view in Views\Account to add a field to enter BirthDate.

Adding Profile information in a different table.

While this post shows you a way where you can easily add profile properties to the User Table itself. Since ASP.NET Identity uses Entity Framework, you can customize profile information as you would like to. For eg. let’s say that you want to add profile information in a different table rather than the same table then you can do the following to your model

Add a new class to store Profile information

Code Snippet

publicclass MyUser : IdentityUser

{

publicvirtual MyUserInfo MyUserInfo { get; set; }

}

publicclass MyUserInfo{

publicint Id { get; set; }

publicstring FirstName { get; set; }

publicstring LastName { get; set; }

}

publicclass MyDbContext : IdentityDbContext<MyUser>

{

public MyDbContext()

: base("DefaultConnection")

{

}

public System.Data.Entity.DbSet<MyUserInfo> MyUserInfo { get; set; }

}

In this case when you run the application you will get the FirstName and LastName in a different table called MyUserInfo

Getting Profile information

When the User Logs in, you can display the profile information by doing the following

Get the current logged in UserId, so you can look the user up in ASP.NET Identity system

var currentUserId = User.Identity.GetUserId();

Instantiate the UserManager in ASP.Identity system so you can look up the user in the system

/* This is the logged in user id. So that I can track which user created this customer */

public string CreatedBy { get; set; }

}

I have a separate repository project that handles database operations (its a class library project). I could just pass the user id from controller to my repository project. But I wanted to grab the current user from my repository project.

Good Day! Sir how can i add model and generate into database? Example i want to add Content Table and i code it to a class name Content.cs inside the folder model. When i run the program, it doesn't create the Table. please help me. Thanks

@Bill What did you figure out on that line of code? I can't figure out what MyUser is, and I am also passing in my DbContext class (the one made that inherits DbContext) and I am getting the red sqwiggly line of death..

How do we we add "scopes" to the Identity providers that come out of the Box with VS2013 RTM. Especially, MicrosoftAccount, Facebook and Google. I saw your example on stackoverflow but it focuses only on Facebook; Is there a general approach for doing this?

Hi Pranav, did your first migration included the membership tables? If it did, have you tried to apply that migration to a SQL Server CE database (assuming you started with a SQL Server database)?

I have and I always get the error "Unable to update database to match the current model because there are pending changes and automatic migration is disabled." It seems that the keys on the membership tables are not defined the same on SQL Server CE and SQL Server.

Do you know of any way to resolve this? I use SQL CE during development, because its faster, so I can stop using it for the moment. But I rather keep using it.

4. Enabled migration and updated the database the AspNetUsers table updated and has two knew coums: Email and Discriminator

But when I try to register a new ApplicationUser a get the following exception in Register

{"Message":"An error has occurred.","ExceptionMessage":"Mapping and metadata information could not be found for EntityType 'CustomIdentityWebAPI.Models.ApplicationUser'.","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Web.Http.ApiController.<InvokeActionWithExceptionFilters>d__1.MoveNext()rn— End of stack trace from previous location where exception was thrown —rn at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)rn at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)rn at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()rn at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__0.MoveNext()"}

I love all of these examples, but to be quite frank, they're all in MVC. What about the rest of us? Too often we're left to try to recode all of these into web forms. Please provide examples in web forms too if you're going to supply these. It would be really appreciated. This one in particular isn't too difficult to translate, but still…

I successfully added the AspnetUser tables to my existing DB, which is what I wanted.

But I cannot add further registration info to my SiteUser table. I get the following message;

The model backing the 'ApplicationDbContext' context has changed since the database was created. Consider using Code First Migrations to update the database.

I don't want code first as I already have a corporate DB that we wish to use. So I tried adding an ADO.NET Data Entity Model – Good stuff, but how do I link it in?

You have offered getting profile information, but you haven't given me a clue as to putting the info! I wish Bill had answered you question re code, as that is my question too.

Also can you provide a sample code of where I would place var currentUserId = User.Identity.GetUserId(); so that the id is added to my SiteUser table. My relationships are already in the db, but I need to see where it should go in the existing code.

Ah, the joy of bleeding edge… If I don't figure this out soon my boss is nagging me to use SimpleMembership! UGH!!!

This may be obvious to everyone else, but it was not to me. So, if you decide to create a second table for additional user information as the second part of this posts shows, and you want those fields for that new table to show on the Register screen: the one thing that is a little different from what they show you is that you have to create a new object for that new table, and then add that object as a parameter when creating the new ApplicationUser object. That way it creates a new row in your second table too. Here is my code that should make what I mean clear: (in the code below my second table was named Person and it had email, phone, and such fields. It also assumes you followed the non-new-table example for birthdate.)

@Alexa You need to map the Identity Model to your custom database schema so that you can add more profile information. Please send me an email at pranav.rastogi@microsoft.com and we can help you get unblocked. We are in the process of documenting this…

Thanks for this tutorial. I'm getting the same error as a few other people here. I tried to add Email as a property to the default user table. I added the column through migrations successfully and there aren't any errors before running. Here is the error message I'm getting when I try to register a new user:

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

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.InvalidOperationException: Mapping and metadata information could not be found for EntityType 'flat_file.Models.ApplicationUser'.

I never liked to user Membership because I don't really want to add 10 tables to my database in order to get the Login information. All those "schema versions, applications, paths, personalizations, …" are good for wizard type applications and not for specific optimized websites.

So I'm trying to understand if it's possible to enhance the Identity and have it work with my User Table. If so, do you know what should I implement? Is that a matter of overriding (or extending) the UserManager.FindAsync and UM.CreateIdentityAsync and related needed methods ??

I wanted to change the data type of the column "ID" in "AspNetUsers" from String(GUID) to Int. I checked msdn.microsoft.com/…/jj591617, but could not find any breakthrough. Though there was a topic explaining about "Configuring the Data Type of a Database Column".

I was able to follow the first half without any issue, however the second half "Adding Profile information in a different table" could use some more details for us newbies.

Specifically, when we edit the code in AccountController.cs, it's easy to save the birthday info, but how do you save the First Name and Last Name? I've tried 20+ variations of what seems like it might work.

The closest I came was with Notso's sample code in the Comments below. First I tried:

I followed the steps that you have listed but I ran into an issue with edit and delete.

Edit: If I try to edit the user that has profile information stored in separate table by doing this

currentUser.MyUserInfo = editUser.MyUserInfo // Where edituser is the model passed from the edit view

Above code create a new record in the MyUserinfo table. and both records are associated with the foreign key relationship. Similarly when we delete the user it only delete it from the AspNetUsers table and leave a record behind in the MyUserInfo table…. Please help… Thanks.

Although I'm new to all this, I followed your instructions and it worked well for me.

However in my case the user will type a screen name to register. The screen name should be UNIQUE and should not exist in the database. How can I check that the screen name doesn't exist in the database before I register the user? Any code would be appreciated because I'n still not familiar with this system. Thanks

I am trying to add two tables that are exactly like the role tables. (Roles and UserRoles tables) I have tried following what you said above, but it adds a field in the user table with that tableID. I would like to set it up just like the UserRoles table where it stores the UserID and the RolesID. How would I go by setting up these 2 tables simular to the roles tables? Also how would you set up relationships between the tables?

Hello everybody, I want to get the properties by declared the Generics collection and without declare the one by one property in the web.config page then want to get these customize properties in the "ProductsCollection.cs" page.

I am unsure where to place the UserManager instantiation. I have modified the Identity model and successfully stored my properties in the AspNetUsers table, however, I am unable to instantiate a UserManager to retrieve profile in my personalisation controller.

Hi, I would like to do the same thing as this tutorial shows however I have started mu project as a database first model. I have added the new column to my table but I can't seem to reference it in the controller.

Thanks for the tutorial. I would like to add user profile information after the user registered and at the first login, iinstead of adding in the registratiojn form. How do I insert data into the new table, is there any ready-to-user api to user, just like accessing the data there?

By the way, what is the best practice for this type of implementation?

Hi ,this is manu. I want actually what ever added some new features to user like(street, City, Pin , State……), this data will display in different view with based on logged user only(not all table data)………..please help us…………..

If you see "The model backing the <Database> context has changed since the database was created." then you've tripped over yet another long outstanding bug in EF. Man, I really hate that framework. I know why you used it in this context, but I really wish there was a better way.

What's the best way to handle multiple registrations and profiles. For example, I want to create a registration view that has 2 options : Manager or Employee. Depending on the option selected, a separate view will ask for different "profile" information to register, and there will be default roles associated with the option selected. I would like to use the existing MVC framework to accomplish this, but I need to know where to begin. Thank you!

The Update-database does not seem to work as I receive an error when I try registering a new user. I’ve found a ‘dirty’ solution by adding the column manually to the AspNetUsers table. Is this ok to do or am I missing something? I also have 2 contexts – not sure if it makes any difference.

How do you extend this so you have access Properties in something like the Site.Master page? Currently you have access to some properties by Context.User.Identity.GetUserName(). If I wanted “First Name” and “Last Name” as properties how would I expose those?

How do insert the claims from the external token into the identity token? I can’t find any info on this.

Here is what I am trying to do. I want to login to say ‘google’ and this works fine. But the access_token from Google seems to get thrown away. But I wish to add this into the claims for the authenticiated user, because I want to make some calls into the Google API’s so I do need to hold onto this access_token. What I want to do then, is add a claim into my identityUser say called “google_access_token” and add the google access token in here so I can reuse it for Google API calls. Is this possible? and if so how do I do it please? For some reason no samples seem to show this.

So first of all when you go to the account controller in the register method the UserName field is already instantiated and is set to use the e mail as the user name. So adding the code snippet you give is redundant.

What I want to know is why, when you do this, it registers the user just fine and they show up in local db just like they are supposed to. But, when try to log in using the new account you just created you cannot. You get an invalid login attempt every time….wtf why. Why does doing this break the login. If you just go back in and change it back to use e mail instead of user name it works just fine.