Recently, a client had a requirement to filter data on the MySite profile page (person.aspx) based on the user whose profile page you were viewing. The particular scenario the client wanted was when user Jim was looking at user Mary's profile page, Jim should see some data (from the BDC) that was filtered to only include items that Mary was involved with. The challenge here was to determine which user's profile the current browsing user was looking at, pull the UserProfile data for that profile, and then provide that data as a filter for other web parts via connections.
It turns out this was quite easy.
Part 1 - Deconstructing person.aspx
The first step was to figure out how SharePoint internally knows which user you are looking at, via the querystring parameters. Person.aspx can take in several different querystring parameters to figure out which user it should display. Following are the available querystring parameters that it can take in (listed in the same order that the page checks for):
| Parameter name |
Description |
| accountname |
User's account name, e.g. (DOMAIN\username) |
| guid |
The user's guid in SharePoint |
| sid |
The user's sid from Active Directory |
| preferredname |
Tries to find a match based on the displayName attribute from Active Directory |
| user |
Takes various iterations of display names or usernames and tries to resolve to a user, by redirecting to _layouts/SelectUser.aspx. |
I figured that there must be some control on that page that reads those querystring values to figure out the user. I also figured that it probably is storing that information in the HttpContext.Items collection, so that it can be leveraged by all the web parts on that page that need access to the profile information.
I cracked open Person.aspx to see what controls are being used, and zeroed in on ProfileViewer (the control that displays Profile Property values).
1: <SPSWC:ProfileViewer id="ProfileViewer" ShowBusinessCardIfEmpty="false" runat="server" />
I looked up ProfileViewer in Reflector, saw that it inherited from ProfileUI, and drilled into that object. Looking in InitControl, I found this code:
1: this.objLoader = ProfilePropertyLoader.FindLoader(this.Page);
Bingo, a static method call to get a loaded profile. Nice. Drilling into the ProfilePropertyLoader, you discover that it is kind of a quasi-singleton, that will create a new object if it is not found in the HttpContext.Items collection, or return one that it already finds. The ProfilePropertyLoader has two properties that return a UserProfile object, ProfileCurrentUser (the profile for the browsing user) and ProfileLoaded (the profile of the user to be displayed, which may be the same as ProfileCurrentUser).
Part 2 - Building the filter web part
Now that I knew how to get the UserProfile object via ProfilePropertyLoader, I set about creating a filter web part, so that I could pass in filter or query values from the UserProfile to other web parts via Connections. MSDN has a great article on creating a Filter provider web part, so I followed that and added my code to get user profile values and pass those into other web parts.
1: public ReadOnlyCollection<string> ParameterValues
2: { 3: get
4: { 5: // Get a reference to the ProfilePropertyLoader,
6: // which contains the reference to the UserProfile
7: Microsoft.SharePoint.Portal.WebControls.ProfilePropertyLoader loader = Microsoft.SharePoint.Portal.WebControls.ProfilePropertyLoader.FindLoader(this.Page);
8:
9: if (loader == null)
10: { 11: return null;
12: }
13:
14: Microsoft.Office.Server.UserProfiles.UserProfile profile = loader.ProfileLoaded;
15:
16: if (profile == null)
17: { 18: return null;
19: }
20:
21: string thirdPartyAppUserID = (string)profile["ThirdPartyAppUserID"].Value;
22:
23: if (string.IsNullOrEmpty(thirdPartyAppUserID))
24: { 25: return null;
26: }
27: List<string> thirdPartyAppUserIDList = new List<string>();
28: thirdPartyAppUserIDList.Add(thirdPartyAppUserID);
29: return new ReadOnlyCollection<string>(thirdPartyAppUserIDList);
30:
31: }
32: }
Using this approach, I was able to pass in a filter value from a UserProfile property to BDC List web parts.