What is Profile?
The ASP.NET profile feature associates information with an individual user and stores the information in a persistent format. Profiles allow you to manage user information without requiring you to create and maintain your own database. In addition, the ASP.NET profile feature makes the user information available using a strongly typed API that you can access from anywhere in your application.
– MSDN Definition
Profile system is ASP.NET feature which is used to save data for each user without writing much code or creating custom tables. We can save any type of value in Profile.
Through this profile system you can save any type of data which .NET Supports and Custom types (that you create by yourself). The most interesting thing is that it will be strongly typed, you don’t have to type cast. Your saved data will be always be persistent even after you come after a long time (days, months, years) unlike Sessions.
The Step follows to implement Profile:
1) To get it working we first need to create tables for user profile. We can do it using tool “aspnet_regsql.exe” which presents in “DriveName:\WINDOWS\Microsoft.NET\Framework\VersionOf.net”.When we will run this tool a GUI will be presented and we can select database to create tables. By Default it creates 11 tables If you want to create only profile table then you can use “aspnet_regsql.exe -A p” command . For getting more details on this tool follow this link http://msdn.microsoft.com/en-us/library/ms229862%28v=vs.80%29.aspx.
2) Add following things in web.config under “system.Web” section. Gray part will be explained on next step.
type="System.Web.Profile.SqlProfileProvider": It saves profile information in a SQL Server database. connectionStringName="ApplicationServices":It is name of your connection string.
3)By assigning properties in web.config you can save and get access to data from database. The property name is user defined you can assign to any name and type refers to the type of the property, in example I have taken ThemeName as String and NoOfVisits to int.
allowAnonymous are set as true which means any user can set the values whether he/she is registered or not registered user.
NOTE:
The type can be set as your custom class like ShoppingCart,Downloaded file etc., but the class should be set as serializable.
To allow anonymous user to you website you have to use in web.config under “system.Web” section.
4)Now we are all set to use Profile. In code behind when we write “Profile” then it intellisense will pop-up and give two properties for that and you can assign the value.
Profile.ThemeName = ”Black”; //See it's not using any typecasting an increasing integer by 1; Profile.NoOfVisits++; //It will save to database Profile.Save(); And now for accessing you can just use like this string themeName = Profile.ThemeName; int CountNoOfVisits = Profile.NoOfVisits;
Using Profile in Web Project
But the 2nd,3rd,4th procedure does not work with Web Project it only works with website.
Actually in website, by default ASP.NET creates ProfileCommon class which inherits from System.Web.Profile.ProfileBase. Through which we can use Profile property but it is not created in Web Project.
So for that, we need to create our own class which inherits from ProfileBase class an in web.config we have to remove property section and add defaultProvider and inherits attribute in profile element.
Web.config will look like: The class will be: namespace ProfileExample.Web.ProfileProvider { /// /// UserProfile class for saving data in DB related to user /// public class UserProfile : ProfileBase { /// /// Getting the instance of UserProfile for current user /// static public UserProfile GetCurrentUser() { if (!HttpContext.Current.Profile.IsAnonymous) { return ProfileBase.Create(HttpContext.Current.Profile.UserName) as UserProfile; } return null; } /// /// Saving and getting page size /// [SettingsAllowAnonymous(true)] public int NoOfVisits { get { return (int)base["NoOfVisits"]; } set { base["NoOfVisits"] = value; //Saving to DataBase Save(); } } /// /// Saving and getting Type of view user has selected /// [SettingsAllowAnonymous(true)] public string ThemeName { get { return (string)base["ThemeName"]; } set { base["ThemeName"] = value; //Saving to DataBase Save(); } } } }
Now we are ready to use this class:
To set the values in profile, now there is no need to explicitly call save method as we have written in class properties:
UserProfile profile = UserProfile.GetCurrentUser(); profile.ThemeName = "Black"; profile.NoOfVisits++; To get from Profile: UserProfile profile = UserProfile.GetCurrentUser(); string themeName = profile.ThemeName string CountNoOfVisits= profile.NoOfVisits;
The upper described code for setting values in Profile works fairly well for register user, but for anonymous(not registered) user, It needs to create table in both aspnet_Users and aspnet_Membership. To do that we have to initialize UserProfile by
UserProfile profile = (UserProfile)ProfileBase.Create(HttpContext.Current.Request.AnonymousID, false);
Create method takes two parameters first is user name in which I have passed anonymous id and second parameter takes whether the user is authenticated or not.
NOTE:
Anonymous user are user who are not registered but when we have specified in web.config. Asp.Net tracks anonymous user. When we are saving in user’s profile, then it creates a new entry in aspnet_Users table. So for each request user makes it creates new entry in table? The answer is no. When we write HttpContext.Current.Request.AnonymousID, If the value is not null then it means Asp.Net is tracking anonymous user and it does not change for each request user makes or after some long time. Internally Asp.Net creates a cookie on client side for anonymous id, if cookie has been deleted from client then new anonymous id will be assigned to user.
Migrating Anonymous user to Register user
Suppose an anonymous user is visiting you website and setting his/her preferences or added a shopping cart. So, at some-point user is going to register or log-in, then you have to import that data in the registered user’s profile data. That can be done through Profile_MigrateAnonymous(object sender, ProfileMigrateEventArgs e) event which will be present in Global.asax.cs. What it does is that, when user is logged in, this event will be fired and then we can Migrate the Anonymous account Profile details to a new authenticated account profile.
For doing this the code is:
/// /// Migrates the Anonymous account Profile details to a new authenticated user /// /// The source of the event. /// The instance containing the Anonymous Profile data void Profile_MigrateAnonymous(object sender, System.Web.Profile.ProfileMigrateEventArgs e) { //Get logged in user profile UserProfile registerUserProfile = UserProfile.GetCurrentUser(e.Context.User.Identity.Name); //Get profile for anonymous user UserProfile anonymousUserProfile = UserProfile.GetCurrentUser(e.AnonymousID); //Save data in register user profile registerUserProfile.ThemeName = anonymousUserProfile.ThemeName; //Delete profile for current anonymous user System.Web.Profile.ProfileManager.DeleteProfile(e.AnonymousID); //Delete member for current anonymous user Membership.DeleteUser(e.AnonymousID); AnonymousIdentificationModule.ClearAnonymousIdentifier(); }
So, on migrating new user to register user, delete details for anonymous user from both tables.
User Profiles are great way to save data but the disadvantage is that it serializes the data and then saves data in that format to the database. So, serialization itself takes time and when on database level we want to get data, then it will be not possible. So,it is better to save small data and which were not being used on management level. Another solution can be that you can create your own Profile table and create custom class by inheriting ProfileProvider and overriding methods, so that there will be no need of serializing the data.
Some links for more indepth knowledge:
http://odetocode.com/articles/440.aspx
http://www.aspiringcraftsman.com/2006/01/microsoft-aspnet-profile/
http://www.vsj.co.uk/articles/display.asp?id=572
http://msdn.microsoft.com/en-us/magazine/cc163624.aspx
For creating custom provider:
http://www.codeproject.com/KB/aspnet/AspNetEFProviders.aspx?msg=3299471