Display user profile picture next to welcome name on MySite

On SharePoint Server

Here is a simple way to add in the logged in users profile picture right before or after the users name in the SharePoint 2010 ribbon.

1.) Add the following to the top of your custom master page right before the doctype:
<%@ Register Tagprefix=”SPSWC” Namespace=”Microsoft.SharePoint.Portal.WebControls” Assembly=”Microsoft.SharePoint.Portal, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>

image

2.) Add in the following control right before the welcome text:
<SPSWC:ProfilePropertyImage PropertyName=”PictureUrlstyle=”float: left; height: 20px;” ShowPlaceholder=”trueid=”PictureUrlImagerunat=”server“/>

image

A nice feature that you can customize is if you don’t want to show a placeholder image if a users has not uploaded a custom picture you can simply change ShowPlaceholder=”true” to “false”. and it will only show a picture if someone has specified a custom one in their profile.

Before:
image

After:
image

NOTE: The resolution is not exactly what we want since it only shows the photo of current user, which means that it will show the user photo of the current page when login user is viewing others’ profile.

Create User Control to Display User Photo

Since the delegate control doesn’t satisfy business requirement, I decided to create an user control to show the picture from User Profile. BTW, you also can get the user photo from hidden “User Information List”; however, there will be an hour outage when user change the photo(Timer Job runs hourly).  Additionally, implement this with Custom Control is more flexible than User Control, but I just try to give you an example.

Step1: Create an User Control

<asp:PlaceHolder ID=”phUserPhoto” runat=”server”>

<asp:Image ID=”imgUserPhoto” runat=”server” Height=”20px” />

</asp:PlaceHolder>

Step2: Add C# code to Page_Load of this control

There are two locations store user photo url: (1) User Information List (2) User Profile

// Using delegate method to get User Information for non-admin user
SPSecurity.RunWithElevatedPrivileges(delegate
{
   try{
    using (SPSite site = new SPSite(SPContext.Current.Site.Url))
    {
       using (SPWeb web = site.RootWeb)
       {
           string[] arr = Context.User.Identity.Name.Split("\\".ToCharArray());
           Method One: Get pictures from User Photo from User Information List
           if (web.Lists.TryGetList("User Information List") != null)
           {
               SPList userList = web.Lists.TryGetList("User Information List");
               // This code also can get the list
               // SPList userList = web.SiteUserInfoList;
               SPQuery query = new SPQuery();
               query.Query = @"<Where><Eq><FieldRef Name='Title' /><Value Type='Text'>" + arr[0] + @"\" + arr[1] + "</Value></Eq></Where>";
               SPListItemCollection loginUser = userList.GetItems(query);
               SPListItem item = loginUser[0];

               if (item["Picture"] != null)
               {
                   SPFieldUrlValue picUrl = new SPFieldUrlValue(item["Picture"].ToString());
                   imgUserPhoto.ImageUrl = picUrl.Url;
               }
           }
           
           Method Two: Get Pictures from /User Photos/Profile Pictures 
           SPPictureLibrary profilePic = (SPPictureLibrary)web.Lists["User Photos"];
           SPQuery query = new SPQuery();
           // Check "Name" column value in User Photos, and the internal name of "Name" is "FileLeafRef"
           query.Query = @"<Where><BeginsWith><FieldRef Name='FileLeafRef' /><Value Type='File'>" + arr[0] + @"_" + arr[1] + "_MThumb" + "</Value></BeginsWith></Where>";
           query.ViewAttributes = "Scope='Recursive'";

           SPListItemCollection loginUser = profilePic.GetItems(query);
           if(loginUser.Count>0)
           {
                SPListItem pic = loginUser[0];
                imgUserPhoto.ImageUrl = "/User Photos/Profile Pictures/" + pic["Name"];
           }
           else
           {
                imgUserPhoto.ImageUrl = "/_layouts/images/014_person_placeHolder_192.png";
           }
       } // end of using Web

       Method Three: Get User Photo from User Profile  
       SPServiceContext serverContext = SPServiceContext.GetContext(site); 
       UserProfileManager profileManager = new UserProfileManager(serverContext);  

       UserProfile up = profileManager.GetUserProfile(Context.User.Identity.Name); 
       if (up[PropertyConstants.PictureUrl].Value != null && !String.IsNullOrEmpty(up[PropertyConstants.PictureUrl].Value.ToString())) 
       { 
           // Check broken link
           Uri urlCheck = new Uri(up[PropertyConstants.PictureUrl].Value.ToString());
           HttpWebRequest request = (HttpWebRequest)WebRequest.Create(urlCheck);
           request.UserDefaultCredentials = true;
           request.PreAuthenticate = true;
           request.Credentials = CredentialCache.DefaultCredentials;
           try
           {
              HttpWebResponse response = (HttpWebResponse)request.GetResponse();
              imgUserPhoto.ImageUrl = up[PropertyConstants.PictureUrl].Value.ToString(); 
           }
           catch(Exception)
           {
              imgUserPhoto.ImageUrl = "/_layouts/images/014_person_placeHolder_192.png";
           }
       } 
       else 
       {
           imgUserPhoto.ImageUrl = "/_layouts/images/014_person_placeHolder_192.png";
       }
       phUserPhoto.Visible = true;
     }// end of Site
  } 
  catch(Exception)
  {
     phUserPhoto.Visible = false;
  }
});

Step3: Add this User Control to Master Page

  1. Register User Control
    • <%@ Register Tagprefix=”myUC” TagName=”UserPhotoDisplay” src=”~/_controltemplates/BrandingMySite/UserPhotoDisplayControl.ascx” %>
  2. Add Control Tag beside the “Welcome” control
    • <myUC:UserPhotoDisplay id=”myUCPhoto” runat=”server”></myUC:UserPhotoDisplay>

Conclusion

I would recommend you to get the user photo from /User Photos since there is a timer job runs hourly to sync the changes in User Profile to User Information List, and the new pic is uploaded to /User Photos then SSP will update picture url in User Profile. When user update and remove its photo, that may induce a display outage.

However, since /User Photos only exists in MySite, if you want to display it on other web app. Getting pics from User Profile would be the best way to do so. This is how the OOTB does in SharePoint 2010. The only problem is when user remove its photo, the User Control still get url from User Profile which has not been updated yet. Therefore, I add the check broken link code to avoid this issue.

Finally, it’s better to implement it as Custom Control which can be used by more than one application. For other web app, you can simply use the delegate control <SPSWC:ProfilePropertyImage />

More Details:

  1. User Profile to SharePoint Full Synchronization (Hourly) – Synchronizes user information from the user profile application to SharePoint users and synchronizes site memberships from SharePoint to the user profile application.
  2. User Profile to SharePoint Quick Synchronization (5 minutes) – Synchronizes user information from the user profile application to SharePoint users who were recently added to a site.

Hope this will help you.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s