How Do I Access the Profile of Other Users Directly in VB.NET?

You may be aware of the new ASP.NET 2.0 Profile feature that allows you to store and retrieve information for the currently logged on user. This Profile feature makes it extremely simple to store user specific information, like a user's address, phone number, or site preferences. (Note: if you're not familiar with ASP.NET 2.0 Profiles check out the section Storing User Profiles in the ASP.NET Quick starts).

But what if you want to access the Profiles data for another user? For example, what if you want to allow a site administrator to change the personal data of all users in your site? The trick to make this possible is to use the ProfileCommon class, which inherits from ProfileBase. This article shows you how you can use this class to access the Profile data for arbitrary users.

Accessing the Current's User's Profile Data

(Note that you can also access a C# version of this article).

Normally, you can access the Profile data from the Profile class that .NET compiles for you on the fly based on the information stored in the <properties> node under <profile> in the Web.config file. Imagine that there is a key called Street of type String in the Web.config (the sample application that you can download at the end of this article has a Web.config file with the property called Street already set up). You'd access the property like this:

  ' Access the property  
  Profile.Country = "SomeStreet"

  ' Change its value
  myStreet = Profile.Country
This gives you strongly typed access to the Profile's properties that are automatically retrieved from and saved to the backing data store, like a SQL Server database.

Accessing a Different User's Profile Data

If you have, for example, a page in the Management section of your site that you use to update the details for one or more users in your database, this code won't work. Every time this code runs, it will only update the current user's Profile; that is, it will only update the Administrator's Profile. To get access to a different Profile for an arbitrary user, you need to create one yourself, and then access its properties. Notice that the term create is a bit of a misnomer. You create an instance of the ProfileBase class, but you don't necessarily create the Profile itself. Only the very first time, when the Profile for the requested user does not exist yet, is the Profile created. In other cases, the existing Profile is retrieved from the database and used. Take a look at the following code to see how this works. First you see the ASPX portion of the code, then you'll see the VB.NET code in the Code Behind file:

<h3>Create New Profile</h3>
  User Name 
  <asp:TextBox ID="txtUserName1" runat="server"></asp:TextBox><br />
  Street
  <asp:TextBox ID="txtStreet" runat="server"></asp:TextBox><br />
  <asp:Button ID="btnSave" runat="server" Text="Create Profile" 
        OnClick="btnSave_Click" /><br />
  <br />
  <br />
<h3>Retrieve Existing Profile</h3>
  User Name
  <asp:TextBox ID="txtUserName2" runat="server"></asp:TextBox><br />
  <asp:Button ID="btnRetrieve" runat="server" Text="Retrieve Profile" 
        OnClick="btnRetrieve_Click" /><br />
  <br />
  <asp:Label ID="lblStreet" runat="server"></asp:Label>

This page contains two areas: one that allows you to create a new Profile by entering a user name and the name of the street. Once you click the Create Profile button, either a new Profile is created or an existing Profile is retrieved from the database for the user name specified in the TextBox txtUserName1. The Profile is then updated with the new information from the txtStreet TextBox.

Once you click the Retrieve Profile button in the second area of the page, the existing Profile is retrieved from the data store, and the Label called lblStreet is updated with the user's data.

To see how this works, take a look at the Code Behind for the page. You'll see two event handlers that deal with the Click events for the two buttons. First, take a look at the code for the Create Profile button:

Protected Sub btnSave_Click(ByVal sender As Object, _
         ByVal e As System.EventArgs) Handles btnSave.Click
  Dim userProfile As ProfileCommon = _
         CType(ProfileCommon.Create(txtUserName1.Text, True), ProfileCommon)
  userProfile.Street = txtStreet.Text
  userProfile.Save()
End Sub

The first line in this method uses the Create method defined in the ProfileBase class to create a new instance of the ProfileBase class. You'll then need to cast it to a ProfileCommon using CType to access the custom properties defined in the Web.config file. As the first argument, the name of the Profile to create is passed. The second argument determines whether the user is treated as authenticated or not. When you pass False instead, the user will be treated as not authenticated, and you won't be able to access properties that are only accessible by authenticated users (that is, properties that have allowAnonymous="false" in the Web.config).

Once you have a reference to the user's Profile, setting properties is as simple as is normally the case. The only caveat is that you must call Save() on the Profile or otherwise the changes are not persisted. Normally, the ASP.NET 2.0 runtime does this for you automatically in the EndRequest event at the end of the execution cycle of an ASP.NET page, provided that the AutomaticSaveEnabled property is set to True , but with this code, you need to call it yourself.

The final step is to retrieve the data again. Not surprisingly, this code is almost identical:

Protected Sub btnRetrieve_Click(ByVal sender As Object, _
          ByVal e As System.EventArgs) Handles btnRetrieve.Click
  Dim userProfile As ProfileCommon = _
          CType(ProfileCommon.Create(txtUserName2.Text, True), ProfileCommon)
  lblStreet.Text = userProfile.Street
End Sub	  

This code creates a new ProfileCommon instance again and then accesses its Street property to update the label.

Accessing the current's user's Profile was already extremely simple, but with the bit of code from this article, accessing arbitrary Profiles is now just has easy. Although this short article demonstrated a quite simple example, it is easy to apply the same principles to everything you know about Profiles, including grouped properties.

Download Files

The download for this article comes as an ASP.NET 2.0 web site with a simple page that demonstrates the code you just saw, and a Web.config file that defines a simple Street property. You'll notice that the download doesn't contain the database; when you run this page, the .NET Framework will automatically create and attach a new database for you that is configured to support the Profiles feature.


Where to Next?

Wonder where to go next? You can read existing comments below or you can post a comment yourself on this article .


Consider making a donation
Please consider making a donation using PayPal. Your donation helps me to pay the bills so I can keep running Imar.Spaanjaars.Com, providing fresh content as often as possible.



Feedback by Other Visitors of Imar.Spaanjaars.Com

On Saturday, July 01, 2006 10:13:09 PM Kendra said:
Thank you so much for this article. I've been working on trying to figure this out forever.
On Wednesday, July 05, 2006 6:04:55 AM Fernando said:
Hi, I found your article 377, thanks for sharing,
quick question, I store user's images in sql server,
I would like to retrieve them from the database using the profile provider.
Any idea on how to do it?

Thanks in advance
On Wednesday, July 05, 2006 9:42:49 PM Imar Spaanjaars said:
Hi Fernando,

You could store the paths to the images in an ArrayList or a generics List (Of String) that is part of the Profile.

I am not sure if you can store actual images in the profile. Not sure how the various formatters work wih that. If I am not mistaken, you can also binary format the properties, so theoretically it should work. Never tried it though, and I wouldn't recommend it. It's probably a lot easier and faster to store the files on disk and keep the path to them in the Profile.

Cheers,

Imar
On Friday, July 21, 2006 9:11:04 PM Manoj Modi said:
Thank you for this.  I was so close BUT the userProfile.Save() was what I needed for it to work....
Not many websites or Books have that..

So thank you
On Sunday, February 04, 2007 6:55:47 PM Chris said:
How do you specify the application name for this functionality.  The example worked for default stuff, but I could not retrieve anything fro profiles set for a specific application name.
On Sunday, February 04, 2007 7:30:11 PM Imar Spaanjaars said:
Hi Chris,

Interesting question. I haven't tried this yet, but here's what I would try:

1. Define multiple profile providers in web.config.

2. Give each provider a different applicationName.

3. Switch the default provider at run-time.

4. Retrieve the data.

5. Switch back.

Hope this puts you on the right track.

Cheers,

Imar
On Tuesday, February 06, 2007 9:59:20 AM Rasheed said:
thank you for the excelent code, which I really don't know since how long I was looking & trying for. thanks again.

in above example we can:
input is: profile name &
output is: get the profile data (street)

is there any code or is possible to:
input is: enter the profile data (street) &
output is: get the remaining fields of profile data (Street & Country etc)

I really appreciate if you could kindly help me.. thanks
On Tuesday, February 06, 2007 10:36:21 AM Imar Spaanjaars said:
Hi Rasheed,

Not by default, as all data is stored in a single BLOB field.

However, with the TableProfile providers you can create your own database scheme, and write custom logic to do this:

http://www.asp.net/sandbox/samp_profiles.aspx?tabid=62

Cheers,

Imar
On Tuesday, February 06, 2007 10:59:40 AM Rasheed said:
thanx a million for the prompt reply Imar,

but I tried this earlier, let me be very specific of what exactly I need:
if a user "A" login and enter some data like servername & password and save it. then user "B" can be able to retrieve this information after authetication & with selecting the user "A" (DropDown User list) to get the stored servername & password.

FYI: I have enabled roles & profiles where user "A" is in group submittor & user "B" is in group accessor.

thanks
On Tuesday, February 06, 2007 11:32:51 AM Imar Spaanjaars said:
Hi Rasheed,

I don't understand the problem. This is exactly what the article is about. In the call to ProfileCommon.Create, pass in the user name of A...

Can you elaborate a little about your problem if this doesn't help?

Imar
On Tuesday, February 06, 2007 12:33:59 PM Rasheed said:
hi Imar,

sorry to disturb you again, let me explain like this:
-----------------------------------------------------------------------------
if user "A" login: The page will be like below

Welcome User "A"
                                   __________
enter the server name: |myserver1 | (textbox1)
      enter the pasword: |myserver1password | (textbox2)
save my details: |click here to save| (button1)

(2 text boxes to enter & save info in the user profile of  "A")
------------------------------------------------------------------------------

if user "B" login: The page will be like below

Welcome User "B"
                                                                __________
enter the server name to get the password :|myserver1 | (text box)
get password: |click here to retreive password| (button)

(on click the result will display the info from profile "A") like below

The password for "myserver1" is | myserver1password | (label)
------------------------------------------------------------------------------

thanks
On Tuesday, February 06, 2007 12:46:48 PM Imar Spaanjaars said:
Hi Rasheed,

Sorry, I have no idea what you're talking about.

I suggest you post this on a forum like http://p2p.wrox.com and provide *lots* more information about your problem when you do so.

Cheers,

Imar
On Wednesday, February 18, 2009 12:57:30 PM Billy Leo said:
Thank you very much for your well described article.
It would have taken me ages to figure this out on my own.
It has helped me out very much!
On Saturday, February 28, 2009 9:37:38 PM Dave Young said:
First very nicely done. Easy to follow and understand. I have implemented your ideas. I added two additional email fields and can update them online.

My question is how do I get all the values from the profile table without knowing what the username is? It's stored as a long string without delimiters.

I'd like to break the two emails into two parts to work with them. Any suggestions would be appreciated. Thanks in advance.
On Sunday, March 01, 2009 9:19:06 AM Imar Spaanjaars said:
Hi Dave,

You can call the ProfileManager.GetAllProfiles method to get a (filtered) list of all existing profiles.

For mor info: http://msdn.microsoft.com/en-us/library/system.web.profile.profilemanager.getallprofiles.aspx

Cheers,

Imar
On Wednesday, October 19, 2011 2:33:41 AM Ewout said:
I'm using Microsoft Visual Basic 2010 in a project and tried your code, but keep getting the error: Unable to cast object of type 'ProfileCommon' to type 'web.ProfileCommon'. on the line 'Dim userProfile As ProfileCommon = CType(ProfileCommon.Create(txtUserName1.Text, True), ProfileCommon)'.
Any ideas how to solve this?
On Wednesday, October 19, 2011 11:55:21 AM Imar Spaanjaars said:
Hi Ewout,

Sounds like you're using a Web Application Project (File | New Project in Visual Studio) rather than a Web Site Project (File | New Web Site).

The former doesn't support Profile out of the box.

Cheers,

Imar

Talk Back! Comment on Imar.Spaanjaars.Com

I am interested in what you have to say about this article. Feel free to post any comments, remarks or questions you may have about this article. The Talk Back feature is not meant for technical questions that are not directly related to this article. So, a post like "Hey, can you tell me how I can upload files to a MySQL database in PHP?" is likely to be removed. Also spam and unrealistic job offers will be deleted immediately.

When you post a comment, you have to provide your name and the comment. Your e-mail address is optional and you only need to provide it if you want me to contact you. It will not be displayed along with your comment. I got sick and tired of the comment spam I was receiving, so I have protected this page with a simple calculation exercise. This means that if you want to leave a comment, you'll need to complete the calculation before you hit the Post Comment button.

If you want to object to a comment made by another visitor, be sure to contact me and I'll look into it ASAP. Don't forget to mention the page link, or the QuickDocId of the document.

For more information about the Talk Back feature, check out this news item.