ASP.NET 2.0 Profile Feature

K. Scott Allen recently published a good post on the new ASP.NET 2.0 Profile system.  The profile system provides an easy way to store and retrieve properties about users on your sites -- both logged-in and anonymous.  It can save you time and effort in providing a richer personalized experience for people using your site.

I published a sample a few months ago that showed how to take advantage of the profile system as part of a site log-in process that you might want to check out.

Hope this helps,

Scott

P.S. I have occasionally heard people say - "personalization is cool, but I'm just building an Intranet site so that isn't so important".  One simple scenario I always point out is the common scenario of saving previous data queries/reports.  You can do this now in only a few lines of code -- and the difference in user-experience can really be dramatic.

 

Published Wednesday, December 28, 2005 4:34 AM by ScottGu

Comments

# re: ASP.NET 2.0 Profile Feature

Wednesday, December 28, 2005 1:50 PM by Michael Teper
Scott, I havent dug too deeply into personalization, but are there API for querying personalization data?

For example, if I were to keep the user's newsletter optin status in the Profile, is there an easy (or otherwise) way for me to retrieve all users who have opted in?

Thanks!

# re: ASP.NET 2.0 Profile Feature

Thursday, December 29, 2005 2:31 PM by Wayne Brantley
Yes, but what about it loading all the personalization data before each page load?? That is a little overkill. What to do with something like 'settings' for a user. Something that does not change except from certain pages. It is something I want to load up once when the user logs in, not pull from the database on every page!

In the example above about saving previous reports/queries. You would not want to have to load all that data on every page load!

# re: ASP.NET 2.0 Profile Feature

Thursday, December 29, 2005 3:45 PM by Marie-Claire
I'm looking here and there for information regarding the ASPNETDB.MDF database files (created under SQL Express): I just want to know what will happen to my users and profile settings when I will migrate my local website to the one provided by my ISP. Since my ISP's SQL server 2005 may contain numerous ASPNETDB.MDF (on behalf of other websites), how will I be able to continue to manage my own data without mixing it with the ASPNETDB.MDF database files of other websites?

Your answer is very important for me because this question is harassing me since too many days and evenings.

Thanks!

Marie-Claire

# re: ASP.NET 2.0 Profile Feature

Saturday, December 31, 2005 9:02 PM by scottgu
Hi Wayne,

The profile data is actually only ever loaded when someone tries to access the profile properties. So if you don't actually write code against the Profile object on a page, it will never be loaded (it uses a lazy-load pattern -- so only loads on first use).

This should give you exactly the behavior you are looking for, and avoid the extra cost of always doing it on each request.

Hope this helps,

Scott

# re: ASP.NET 2.0 Profile Feature

Sunday, January 1, 2006 9:22 AM by LukCAD
Some my thougths about personalization of controls into body of page:
I did next for personalisation of ascx controls:
for everyone control per page I compare the role of active userID with the controlname.ID directly on client side or on server side without additional retrieving that roles from database before every new page creating. I had next:
- session with ClientID and roleID (i got it when application start when coockie is, or by retrieving first tiime from database after every new LogIN)
- nameofcontrol consists from two parts: nameofcontrol and roleid of authentificated user.

In result all my clients programms can easily to retrieve the rule of working for every part of page content by retrieving roleid from name of control.(it is very easy and notneed postback that roleid from server side)

Sincerely, LukCAD

# re: ASP.NET 2.0 Profile Feature

Thursday, January 5, 2006 5:37 AM by Glyn Simpson
Personalization seems pretty good, but it doesn't appear to have an administrative overview.

I wanted, for example, to view the profiles of people on an administrative form, such as their preferred name, or other custom data that is in the profile.

It doesn't seem that possible to extract all of this easily, through an ObjectDataSource or otherwise..

Glyn

# re: ASP.NET 2.0 Profile Feature

Thursday, January 5, 2006 7:02 AM by scottgu
Hi Glyn,

You can use the System.Web.Profile.ProfileManager class to gain access to the system's profile data.

ProfileManager.GetNumberOfProfiles() will return the number of profiles in the system.

You can then use ProfileManager.GetAllProfile() to page through these profiles and get access to their values (if you hook this up to an ObjectDataSource and a GridView it should be pretty easy).

You could then build an admin page that provided access to the what you are looking for.

Does this help answer your scenario? Let me know if you want me to provide more details.

Thanks,

Scott

# re: ASP.NET 2.0 Profile Feature

Sunday, January 8, 2006 8:02 PM by Giorgio
You cannot retrieve custom properties! I'm having this problem and it seems that the ASP.NET Microsoft team didn't think about this!!

The profilemanager class has the following methods:

- DeleteInactiveProfiles. Enables you to delete all profiles older than a specified date.
- DeleteProfile. Enables you to delete a profile associated with a specified username.
- DeleteProfiles. Enables you to delete a set of profiles.
- FindInactiveProfilesByUserName. Returns a collection of ProfileInfo objects that represent profiles that have been inactive since a specified date and match a specified name.
- FindProfilesByUserName. Returns a collection of ProfileInfo objects that represent profiles that match a specified username.
- GetAllInactiveProfiles. Returns a collection of ProfileInfo objects that represent profiles that have been inactive since a specified date.
- GetAllProfiles. Returns a collection of ProfileInfo objects that represent all profiles.
- GetNumberOfInactiveProfiles. Returns an integer that represents the number of profiles that have been inactive since a specified date.
- GetNumberOfProfiles. Returns an integer that represents the total number of profiles.

None of these methods return a complete profile, although many of the methods return a collection of ProfileInfo objects. The ProfileInfo object represents the following profile properties:

- IsAnonymous. A Boolean value that represents whether or not the profile is associated with an anonymous or authenticated user.
- LastActivityDate. A date and time that represents the last time the profile was accessed.
- LastUpdatedDate. A date and time that represents the last time the profile was updated.
- Size. An integer value that represents the size of the profile as stored by the profile provider.
- UserName. A string that represents the user associated with the profile.


I would like to retrieve all the custom properties that I've configure on the Web.config and none of the available methods allows to do this!!!
WHY MAKE PROFILES AVAILABLE IF THEN THEY DON'T SUPPLY ANY METHOD TO RETRIEVE THE CUSTOM PROPERTIES?

Can anybody tell me how can I retrieve all users that have a profile and bind all custom properties to a gridview?

# re: ASP.NET 2.0 Profile Feature

Tuesday, January 10, 2006 10:05 AM by Rushi
Hi Scott,

I have a methods which takes UserID of the logged in user as an argument.Is there any way I can get access to profile's UserID without running a query on aspnet_users table??

Thanks
Rushi

# re: ASP.NET 2.0 Profile Feature

Tuesday, January 10, 2006 10:01 PM by scottgu
Just to follow up on Josh's comment, you can also then write:

ProfileInfoCollection pc = ProfileManager.FindProfilesByUserName(ProfileAuthenticationOption.All, "nameprefix%");

foreach (ProfileInfo pi in pc) {

}

To iterate over the profileInfo objects based on a name query you provide. Within the foreach you should be able to use the code that Josh provided above to lookup the profile and add it to a collection that you then databind against.

Hope this helps,

Scott

# re: ASP.NET 2.0 Profile Feature

Wednesday, January 11, 2006 12:44 AM by scottgu
Hi Rushi,

You can access the User.Identity.Name property on a page (or via HttpContext) to get access to the logged in user's UserID. This obtains the information for the security context (example: FormsAuthentication ticket or Windows identity token) -- so doesn't need to hit the aspnet_users table.

Hope this helps,

Scott

# re: ASP.NET 2.0 Profile Feature

Monday, January 23, 2006 1:36 PM by Bela
Almost there. Once I have a ProfileInfo object - how can I get access to the custom profile information (specified in web.config?)

# re: ASP.NET 2.0 Profile Feature

Monday, June 19, 2006 1:20 PM by Justin
Hi Bela,
The ProfileInfo object exposes the UserName property, which you can use to get a ProfileCommon object, using Profile.GetProfile(username). Your ProfileCommon object then exposes your custom properties you set in your web.config. Try something like this...

//c#
ProfileInfoCollection pc = ProfileManager.GetAllProfiles(ProfileAuthenticationOption.All);
foreach (ProfileInfo pi in pc) {
ProfileCommon prof = Profile.GetProfile(pi.UserName);
}

'vb
Dim pc As ProfileInfoCollection = ProfileManager.GetAllProfiles(ProfileAuthenticationOption.All)
       For Each pi As ProfileInfo In pc
           Dim prof As ProfileCommon = Profile.GetProfile(pi.UserName)
           'get your values from prof
       Next

Regards,
Justin

# re: ASP.NET 2.0 Profile Feature

Friday, August 11, 2006 10:45 AM by Richard
scottgu I assume your'e talking about the default provider when you say "The profile data is actually only ever loaded when someone tries to access the profile properties." and that it uses a lazy-load pattern. If I'm right, the default provider is that of type 'System.Web.Profile.SqlProfileProvider'. When looking through the sourcecode for that class I cannot seem to find any traces of that lazy-load mechanism... If I were to implement a custom provider, how would I go about and implement such a mechanism. I assume that the property IsDirty would be used in some way. Best regards, Richard

# re: ASP.NET 2.0 Profile Feature

Saturday, August 12, 2006 3:53 PM by ScottGu

Hi Richard,

The lazy-loading actually happens via the Profile API when it loads the provider.  Basically it doesn't call the ProfileProvider until someone tries to access one of the Profile API's properties.  That way you don't need to-do anything special within your provider to get this behavior.

Hope this helps,

Scott

# re: ASP.NET 2.0 Profile Feature

Sunday, August 13, 2006 7:54 PM by sarp
hi everyone, I am planning to use profile info to store Table/Record Authorization of the user. After reading all your comments and investigating profile class I am not sure to with profile anymore. An sql table to store the recordbase authorization might be easier. Do you have any comment on this subject?

# re: ASP.NET 2.0 Profile Feature

Monday, August 14, 2006 12:23 PM by ScottGu

Hi Sarp,

One option you can look at is to map the Profile API against a SQL table or SPROC directly.  This provider enables this support pretty easily: http://weblogs.asp.net/scottgu/archive/2006/01/10/435038.aspx

Hope this helps,

Scott

# re: ASP.NET 2.0 Profile Feature

Sunday, August 27, 2006 6:51 PM by VinceB
Is there a way to just get the guid id for the user from the membership provider or the profile provider, without having to do a select on the user table. Vince

# re: ASP.NET 2.0 Profile Feature

Tuesday, August 29, 2006 12:31 AM by ScottGu

Hi Vince,

There is no way to get the GUID without hitting the table. However, you could use the username as the access key -- this is cached from the forms-auth cookie and so is super efficient to access.

Alternatively, you could retrieve the GUID once and then cache it within the private security storage section of the FormsAuthentication ticket.  This will encrypt and stick it in the forms-auth cookie as well, and allows you to avoid hitting the database on subsequent requests.

Hope this helps,

Scott

# re: ASP.NET 2.0 Profile Feature

Saturday, September 2, 2006 12:09 PM by ScottGu

Hi Sam,

Yep -- you can get access to the UserID column value through that property on the MembershipUser object returned from Membership.GetUser().

In general, I'd probably still recommend that you use the username (as a string) value as your keys elsewhere -- since that will enable you to change your membership storage implementation at a later date (for example: store in another database or within active directory) wihtout you having to worry about dependencies you might have on the origional GUID value.

Hope this helps,

Scott

# re: ASP.NET 2.0 Profile Feature

Tuesday, September 12, 2006 10:53 AM by ScottGu

Hi Sam,

One approach to take would be to never delete users, but just mark them as inactive (the Membership API supports this).  That way you never need to worry about adding a duplicate user to the system.

Hope this helps,

Scott

# re: ASP.NET 2.0 Profile Feature

Wednesday, October 4, 2006 4:23 AM by Jonathan
okay I figured out solution to my own problem. I assigned a value to a placeholder profile field, call Save() -> UserName is populated with the UserId Guid.

# re: ASP.NET 2.0 Profile Feature

Wednesday, October 18, 2006 5:25 PM by PARUS
Hi. Maybe somebody could help me. Everytime I start application both SetPropertyValues and GetPropertyValues fired. But SetPropertyValues fired out-side of my application and I never call Profile.Save method. Maybe somebody could help me in this or had the same behaviour? Regards, Valentyn. Plase, diblicate your answer to bootloader@lit.ru

# re: ASP.NET 2.0 Profile Feature

Thursday, October 19, 2006 11:59 PM by ScottGu

Hi Parus,

That is very odd.  Can you set a breakpoint on your provider to see what the call-stack of the caller is?

Thanks,

Scott

# re: ASP.NET 2.0 Profile Feature

Monday, October 23, 2006 9:29 PM by Scorpion
is there a way to access profile in web custom control??? i created some property in web.config,, and i would like to access those value in a web custom control..

# re: ASP.NET 2.0 Profile Feature

Wednesday, October 25, 2006 9:48 PM by scorpion
i created some custom properties in web.config,, how can i access those properties in web custom control??? can any one help me...

# re: ASP.NET 2.0 Profile Feature

Thursday, October 26, 2006 1:12 AM by ScottGu

Hi Scorpian,

You can write the below code to get access to a late-bound Profile object:

HttpContext context;

context = HttpContext.Current;

context.Profile

There are then get/set methods on this context.Profile object that you can use within your custom control.

Hope this helps,

Scott

# re: ASP.NET 2.0 Profile Feature

Tuesday, November 21, 2006 11:56 PM by Anthony

Hi Scott,

Thanks for the tip, but it wasn't the answer i was looking for.

I just wanted to know the reasons behind your recommendation of using UserName as the FK instead of UserId. As I mention in my last post, it seems very difficult to get the UserId with hitting the database with membership.GetUser() whereas UserName is easily available from Context.User.UserName.

Hope its more clear this time.

thanks heaps Scott!

Anthony

# re: ASP.NET 2.0 Profile Feature

Sunday, November 26, 2006 3:10 PM by ScottGu

Hi Anthony,

You can retrieve a userkey from the membership provider by writing code like this:

MembershipUser user = Membership.GetUser("username");

object userKey = user.ProviderUserKey;

This enables a Membership provider to surface the primary key they are using to store the user.  In the case of the default SQLMembershipProvider that ships with ASP.NET 2.0 this is a GUID value.

Hope this helps,

Scott

# re: ASP.NET 2.0 Profile Feature

Sunday, November 26, 2006 11:25 PM by Anthony

Hi Scott,

Sorry to drag this on, but one last question.

If I had a User intensive website, where most of the CRUD requires the use of an UserId parameter.

Now, what would be the best option?

1. Call Membership.GetUser("Username") just before each CRUD inside each Page?

2. Get my SP to lookup the userId given the username and applicationId

3. store the UserId inside the UserData field in the cookie?

4. Use username as the FK in all my tables.

5. Something better than the above?

thanks

Anthony

# re: ASP.NET 2.0 Profile Feature

Wednesday, November 29, 2006 1:10 PM by ScottGu

Hi Anthony,

Sorry for the delay in getting back to you on this!

Any chance you could send me email on this topic (scottgu@microsoft.com)?  That way we can continue to conversation and I can also help loop in a few other folks to get their advice.

Thanks,

Scott

# re: ASP.NET 2.0 Profile Feature

Thursday, November 30, 2006 9:15 AM by MartinG

Hi Scott,

How does the profile system handle visits from crawlers like googlebot? Since it obviously can't write a persistent cookie does that mean a new GUID is generated for each request?

Thanks,

Martin

# re: ASP.NET 2.0 Profile Feature

Thursday, November 30, 2006 4:23 PM by John R.

Is there a way to lookup profiles other than by using username (FindProfilesByUserName)?  For instance, I have a page where I would like to show all users from a certain state.  I'd hate to have to call GetAllProfiles and filter out the ones not in the state I'm interested in.  This could take a long time if the site has a lot of users.

# re: ASP.NET 2.0 Profile Feature

Friday, December 1, 2006 1:02 AM by ScottGu

Hi Martin,

If you are using authenticated profiles (the default), then you only issue a profile when a user logs in (and since bots don't login you never issues a profile cookie).

With anonymous profiles they'll be issues a cookie - although since they never store anything on the server it won't persist anything in the profile store.

Hope this helps,

Scott

# re: ASP.NET 2.0 Profile Feature

Wednesday, December 6, 2006 6:58 PM by Anthony

Hey Scott,

Did you get my email from last week?

Just wondering if it ever reached your inbox.

thanks

Anthony

# re: ASP.NET 2.0 Profile Feature

Wednesday, December 13, 2006 8:52 AM by MikeS

Hi Scott,

Little different issue here.

I'm creating a custom profile provider for Oracle. I am unable to see the default/intrisic Profile object. i.e. it does not show up in intellisense.

I've clean compiled, checked web.config profile declaration 100 times. I don't have a fully functional (it's stubbed) provider yet but it should show up.

I've even tried defining the default sql profile provider in web.config and do not see the intrinsic Profile object.

What must happen to make the Profile instance show up?

# re: ASP.NET 2.0 Profile Feature

Wednesday, January 17, 2007 2:11 PM by Christian Blunden

Hey Scott,

I am trying to implement custom WCF membership and profile providers. All seems to be working as it should.

However, we have opted to not use the default ASP.Net membership controls such as login, User Registration Wizard etc. This is due to an existing control framework in place.

My problem seems to be that the default providers fire internal events, which I cannot reproduce.

Example: the Membership.ValidateUser() method calls;

WebBaseEvent.RaiseSystemEvent(null, 0xfa2, username);

Could you provide any clarity on how I might handle LoggingIn, setting the HttpContext.User and triggering a MigrateAnonymousEvent?

Many thanks

Christian

# re: ASP.NET 2.0 Profile Feature

Friday, January 19, 2007 9:31 PM by ScottGu

Hi Christian,

Any chance you could send me an email with details about this problem?  I can then loop you in with some folks who can help provide an answer.

Thx!

Scott

P.S. Have you also looked at the source code for the default ASP.NET Provider implementations: http://weblogs.asp.net/scottgu/archive/2006/04/13/Source-Code-for-the-Built_2D00_in-ASP.NET-2.0-Providers-Now-Available-for-Download.aspx

# re: ASP.NET 2.0 Profile Feature

Friday, February 2, 2007 4:27 PM by Nathan

am relatively new to the asp.net 2.0 frame. I am using the role,membership and profile model. The backend for the application is a Sql Sever 2005 database. While the roles and membership work as intended , I am unable to use Profile. For one the 'Profile' class does not show up in the intellisense. I always get the error :

'The name 'Profile' does not exist in the current context '

On the back end , i can see the aspnet_Profile table has been created.

Intially when i used the aspnet_regsql.exe tool I only utilized the 'm' and 'r' options (membership and roles). I didn't need to store addtional user specific information. However the requirements changed and I now need to add user-personalization data so i thought using Profiles would be the way to go ( it seemed to take a lot less time than creating my custom tables).So I then ran the aspnet_regsql.exe tool, but this time only with the 'p' option(Profile). Could that be the reason why it isn't working.

This is what my web.config looks like:

<?xml version="1.0"?>

   <configuration>

      <appSettings>

         ..................

      </appSettings>

     <connectionStrings>

       <clear />

       <add name="DevDB" connectionString="....../>

      ..............

     </connectionStrings>

<system.web>

  ......................................

  ......................................

  <roleManager enabled="true" defaultProvider="CustomizedRoleProvider">

     <providers>

        <clear/>

        <add name="CustomizedRoleProvider" type="System.Web.Security.SqlRoleProvider"

               connectionStringName="DevDB"  applicationName="MyApplication" />

     </providers>

  </roleManager>

  <membership defaultProvider="CustomizedMembershipProvider">

     <providers>

        <clear/>

        <add name="CustomizedMembershipProvider" type="System.Web.Security.SqlMembershipProvider"

                connectionStringName="DevDB"   applicationName="MyApplication" />

     </providers>

  </membership>

  <profile enabled="true" defaultProvider="CustomizedProfileProvider">

     <providers>

        <clear />

       <add name="CustomizedProfileProvider" type="System.Web.Profile.SqlProfileProvider"

              connectionStringName="DevDB" applicationName="MyApplication" />

    </providers>

   <properties>

       <add name="TestStartTime" type="System.DateTime" allowAnonymous="false"

               serializeAs="String" defaultValue="00/00/0000"/>

  </properties>

 </profile>

</system.web>

configuration>

# re: ASP.NET 2.0 Profile Feature

Friday, February 2, 2007 5:52 PM by Nathan

I am trying to use Profiles, but i keep getting the error:

The name Profile does not exist in the current context

# re: ASP.NET 2.0 Profile Feature

Saturday, February 10, 2007 1:55 PM by ScottGu

Hi Rachel,

I believe you want to-do this instead:

ProfileCommon userProfile = (ProfileCommon) Profile.Create("UserName");

userProfile.TestProperty = "Hello World";

userProfile.Save();

Note that you'll need to use the "Save()" method at the end to save the profile changes - since you are creating a custom profile instance the page won't do it for you.

Hope this helps,

Scott

# re: ASP.NET 2.0 Profile Feature

Tuesday, February 20, 2007 12:13 PM by Will

If you want to access a particular profile property (that you've set in web.config) from outside the ASP.NET scope of ProfileCommon you need to use ProfileBase.Create(). Of course, you lose strong typing, etc.

// given a MembershipUser user

ProfileBase pb = ProfileBase.Create(user.UserName);

object pvalue = pb.GetPropertyValue["yourpropertyname"];