Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


Finalize(): Profiles from Afar

Discover a few tips for using the Profile features of the ASP.NET framework.




Application Security Testing: An Integral Part of DevOps

have a friend with whom I have a never-ending IM conversation. You know what I mean: We never say "Hello" or "TTYL". Conversations just gradually flow in and out, as in some extended stream of consciousness. Ever since I left Los Angeles, this friend and I can't meet for lunch, take a hike up the hill, or a morning bike ride around Pasadena. We both miss these benefits of proximity and self-employment. So, we make do with IM.

The little IM popup window appears regularly with comments on a recent TV show ("I already miss West Wing"), the state of the dog ("Taking Max out for a walk") or his owner ("Feeling kinda cruddy this morning"), and the important questions of life ("Should I have toast or a bagel this morning for breakfast?"), without introduction, greeting, or context. One morning, this one pops up (and, as you might imagine, acted as the germination of the idea for this article): "How can I retrieve Profile information from a class library called from a Web page?"

Amazingly, I had just completed a courseware chapter on the Profile features in ASP.NET, and so I figured I had to have something in there that would help. For those unclear on the concept, you can define a schema for user-oriented profile information by adding a section to your site's Web.config file, like this:

<profile> <properties> <add name="LastVisitedDate" type="System.DateTime" allowAnonymous="true"/> <add name="FullName" type="System.String" allowAnonymous="true"/> <add name="PrivateInfo" type="UserInfo"/> <group name="LocationInfo"> <add name="State" type="System.String" allowAnonymous="true"/> <add name="PostalCode" type="System.String" allowAnonymous="true"/> </group> </properties> </profile>

At design time, the language compiler takes this information and generates an object of type ProfileCommon named Profile, with properties that match the properties defined in the configuration file (LastVisitedDate, FullName, PrivateInfo; of the type UserInfo, a class defined in my sample project, containing Birthdate and SSN properties; and LocationInfo, a "structure" of properties defined in web.config, containing State and PostalCode properties). In your site's code, you can include code like this to retrieve and set properties of the current user's profile:

[Visual Basic] If Profile.LastVisitedDate <> _ DateTime.MinValue Then ' Only display the date if you've ' already been through here. lblLastDate.Text = "You last visited on " & _ Profile.LastVisitedDate.ToShortDateString() End If Profile.LastVisitedDate = DateTime.Today [C#] if (Profile.LastVisitedDate != DateTime.MinValue) { // Only display the date if you've // already been through here. lblLastDate.Text = "You last visited on " + Profile.LastVisitedDate.ToShortDateString(); } Profile.LastVisitedDate = DateTime.Today;

You can work with the auto-generated Profile object, loading a profile for any user (the ASP.NET profile management code stores each user's profile information in a database-a SQL Express database named ASPNETDB.MDF, by default), using code like this:

' Call the DisplayData procedure like this: ' DisplayData(Profile.GetProfile("Russ")) Private Sub DisplayData( _ ByVal currentProfile As ProfileCommon) ' Retrieve data from the selected profile, and display in ' controls on the page. txtName.Text = currentProfile.FullName ' Display the rest of the data here... End Sub

The real problem comes when you attempt to retrieve profile data in a project outside the current site. You define all the schema for the Profile object in web.config, but a class library project doesn't have the web.config available to it, nor will Visual Studio automatically create the Profile object for you unless you're in a Web project, and you've set up the schema in the configuration file.

What can you do to solve this problem? I first looked into the ProfileManager class, which almost seems to provide the information you might need. You could write code like this, in order to find a particular profile:

' Set a reference to System.Web, and add ' the following to the top of the file: Imports System.Web.Profile ' or in C#: ' using System.Web.Profile; For Each info As ProfileInfo In _ ProfileManager.FindProfilesByUserName( ProfileAuthenticationOption.Authenticated, "Ken") System.Diagnostics.Debug.Print(info.UserName) Next

The problem is that the ProfileInfo class provides only the minimum values for each profile, including the UserName, LastActivityDate, and a few other properties—it doesn't include any of the properties added through the schema you define in web.config.

The answer, which my friend finally found on his own, is to use the System.Web.Profile.ProfileBase class to do the work. You can use this class's Create method to retrieve the specified user's profile information from the current data store, even though the currently running code (in a class library) doesn't have direct access to the web.config schema. For example, you could write code like this to create a ProfileBase object and retrieve a profile property:

[Visual Basic] Public Function GetState( _ ByVal userName As String) As String Dim profile As ProfileBase = _ ProfileBase.Create(userName) Return profile("LocationInfo.State") End Function [C#] public string GetState(string userName) { ProfileBase profile = ProfileBase.Create(userName); Return profile["LocationInfo.State"]; }

As you can tell, you're on your own when retrieving information from the ProfileBase instance you create-the class exposes the profile values in a dictionary, so you supply the string index, and the class provides the corresponding value.

Is this a tip of earth-shattering importance? Probably not. On the other hand, it's nearly impossible to retrieve the profile information from outside a running Web site by any other means, so it's nice to know that this technique exists. (You'll also find it useful to investigate the System.Profile.ProfileManager class, which provides lots of useful methods for managing profiles, including the important DeleteInactiveProfiles—otherwise, there's no way to remove the myriad anonymous profiles you'll find clogging your site's ASPNETDB database.) And in the same IM conversation, I learned all sorts of other interesting, if not quite so useful, factoids. If only every IM thread was so fruitful.

Ken Getz is a senior consultant with MCW Technologies and splits his time between programming, writing, and training. He specializes in tools and applications written in Visual Studio .NET and Visual Basic. Ken is the author of the highly rated .Finalize() column in CoDe Magazine. He is also the co-author of several best-selling books, including Access 2002 Developer's Handbooks with Paul Litwin and Mike Gunderloy, Visual Basic Language Developer's Handbook with Mike Gilbert, and VBA Developer's Handbook with Mike Gilbert (Sybex). He co-wrote several training courses for Application Developer's Training Company, including VB.NET, ASP.NET, Access 2000 and 97, Visual Basic 6, and Visual Basic 5 seminars. He has also recorded video training for AppDev covering VB.NET, ASP.NET, VB6, Access 2000, and Access 97. Ken is a frequent speaker at technical conferences and has spoken often at Microsoft's Tech-Ed conference. Ken's also a technical editor for Access-VB-SQL Advisor magazine and a columnist for Informant Publications' asp.netPRO magazine..
Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date