Recently i was tasked with creating a Silverlight LOB application that query SharePoint for it's data.
One function of this application has to do with showing the details of a user based on the information found in SharePoint's user profile service, and in this tutorial i will focus on getting this information from SharePoint to Silverlight.
In this tutorial we will build a simple application that shows the details of the user from SharePoint's user profile service using SharePoint's Client Object Model.
1) Download the starter project and open it in Visual Studio 2010.
2) Examine the project and you'll see that we have a MainPage.xaml that holds a hyperlink button and a ChildWindow control to show the user data.
3) Add a reference to SharePoint's COM dlls located at C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\ClientBin\ directory on your SharePoint server.
4) Add service reference to SharePoint's user profile web service located at http://<your server url>/_vti_bin/userprofileservice.asmx and name it SPUserProfileService:

5) Once the files are referenced we are ready to get started. Add a "Loaded" event to the MainPage method as shown here:
public MainPage()
{
InitializeComponent();
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
}
6) In the new MainPage_Loaded method, we will handle the initiation of our web service and attach an event handler for the "GetUserProfileByName". Add a global private variable for the web service's soap client and the following code to the Main_Loaded method:
private SPUserProfileService.UserProfileServiceSoapClient _proxy;
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
_proxy = new SPUserProfileService.UserProfileServiceSoapClient();
_proxy.GetUserProfileByNameCompleted += new EventHandler<SPUserProfileService.GetUserProfileByNameCompletedEventArgs>(proxy_GetUserProfileByNameCompleted);
}
7) To get the properties of the current logged in user, we call the "GetUserProfileByName" method of the web service and pass it the value of null. Add the following code to your "HyperlinkButton_Click" method:
private void HyperlinkButton_Click(object sender, RoutedEventArgs e)
{
_proxy.GetUserProfileByNameAsync(null);
}
8) To test our setup, let's use MessageBox to show the value of the first user property returned by the web service. Add the following code in the proxy_GetUserProfileByNameCompleted method:
void
proxy_GetUserProfileByNameCompleted(object sender, SPUserProfileService.GetUserProfileByNameCompletedEventArgs e)
{
MessageBox.Show(e.Result[0].Values[0].Value.ToString());
}Notice that the Values property is also an IEnumerable, which means that every property can return more than one value.
9) Build the project, upload the .xap file to your SharePoint site, add a Silverlight web part to your page and finally point the web part to your xap. Once done it will look like this:

10) Try to click to hyperlink. Hmm, nothing shows up and a javascript error is looking at us from the bottom of our browser window. If you debug your application this is the exception you will face:
The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://microsoft.com/webservices/SharePointPortalServer/UserProfileService:GetUserProfileByNameResponse. The InnerException message was 'Error in line 1 position 528....
11) What happens is that Silverlight cannot understand (deserialize) the result of the web service, as ASMX uses a slightly different schema for its GUID and char types. Following this awesome post by the Silverlight Web Services Team, we are able to create a "bridge" (message inspector) for our call.
12) Download the sample from the post mentioned above (link again here) and add AsmxBehavior.cs and AsmxMessageInspector.cs files to our solution. Don’t forget to change the namespace to ours in both files. (You might need to add a reference to System.Xml.Linq as well).
13) To make use of the new "bridge" all we need to do is add one line to our MainPage_Loaded method:
void
MainPage_Loaded(object sender, RoutedEventArgs e)
{
_proxy = new SPUserProfileService.UserProfileServiceSoapClient();
_proxy.Endpoint.Behaviors.Add(new AsmxBehavior());
_proxy.GetUserProfileByNameCompleted += new EventHandler<SPUserProfileService.GetUserProfileByNameCompletedEventArgs>(proxy_GetUserProfileByNameCompleted);
}
14) Build the solution again, upload the .xap file to the same directory and refresh the page. Try to click on the hyperlink button again. Cheers! our message box now shows us the first of the user profile properties: the GUID.
15) Now that we have access to the ObservableCollection of the profile properties we can loop through it and find the ones we need. To cut things short: Image is located at position 15, First and Last names are 2 and 4, Title is 10 and phone is 8.
16) To show the ChildWindow we need to pass it's constructor a UserProfileClass class. Once we do that we can use the Show method and pop up the ChildWindow. Change the "proxy_GetUserProfileByNameCompleted" method as follows:
void proxy_GetUserProfileByNameCompleted(object sender, SPUserProfileService.GetUserProfileByNameCompletedEventArgs e)
{
UserProfileClass upc = new UserProfileClass()
{
FirstName = e.Result[2].Values[0].Value.ToString(),
LastName = e.Result[4].Values[0].Value.ToString(),
ImageUrl = e.Result[15].Values[0].Value.ToString(),
Title = e.Result[10].Values[0].Value.ToString(),
Phone=e.Result[8].Values[0].Value.ToString()
};
UserInfoChildWindow uicw = new UserInfoChildWindow(upc);
uicw.Show();
}
17) Build the application again, upload the .xap and try it out again... You should see something like this (provided that your profile in the User Profile Service has these properties):
This concludes the tutorial. We have built a simple application to show the User Profile information from SharePoint 2010 to our users using Silverlight 4. This tutorial leave a lot of room for your personal exploration so feel free to email me with your solutions and I’ll post them on a follow up post later next month.
To download the finished solution click here.