You may have noticed that in an ASP.NET application, whenever you access a property in a user's profile, the last activity date is automatically updated for that user. This may not the behavior you want, especially when you're dealing with users who are offline. Here's why it happens, and how to alter this default behavior.
Let's say you need to populate some web controls with values from a user's profile:
In this code, by simply reading these profile properties, you're updating the last activity date for this user (more specifically, the value of the LastActivityDate column of the user's record in the aspnet_Users table is set to the current date and time). This isn't really a problem, as long as you're only dealing with a currently online user, as in the above example.
But let's say you have an administration page that allows you to access profiles of offline users, like this:
The last activity date of this offline user will be updated too. In this case, the LastActivityDate column in aspnet_Users essentially means the last time the user's record was accessed, whether that user is online or not -- at least as far as ASP.NET is concerned. This may not be the desired behavior in your particular application, especially if you use methods like this:
The Membership.GetNumberOfUsersOnline method returns the number of users where the last activity date is greater than the current time less the value of UserIsOnlineTimeWindow, which by default is 15 minutes (this can be altered in the configuration file). You can see that if your application accesses profile properties for offline users, this number won't be accurate, since GetNumberOfUsersOnline uses LastActivityDate to derive its value. Any offline users whose profile properties were accessed within the time window would be counted as "online" by this method, even though they weren't.
How ASP.NET Accesses Profile Properties
When an application in which user profiles are enabled is started, ASP.NET creates a new class of type ProfileCommon, which inherits from the ProfileBase class. An instance of this class is used as the value of the Profile object.
Properties are added to this automatically-generated ProfileCommon class for each property defined in the profile configuration section. These properties call the GetPropertyValue method of ProfileCommon to retrieve untyped values from the ProfileProvider. The get accessor casts the untyped value as the specified type, then returns the property's value. This mechanism provides strong-typing for the Profile object.
Okay, let's review what we have so far. A reference in code to any profile property generates a call to ProfileCommon.GetPropertyValue. This, in turn, generates a call to the ProfileProvider GetPropertyValues method.
The default profile provider for ASP.NET is of type System.Web.Profile.SqlProfileProvider, which as we see below provides access to profile data by running the aspnet_Profile_GetProperties stored procedure.
Below is the code for aspnet_Profile_GetProperties:
You can see in the last part of this stored procedure (lines 26 - 31), if a profile is found for the specified user, LastActivityDate is updated. You can alter this behavior by simply commenting out or deleting these lines.
That way, the last activity date of a user won't be updated when you access that user's profile from your code.