Friday, 29 November 2013

Set UserProfile Picture using Client APIs in SharePoint 2013

With the SharePoint 2013 Client APIs, you can only read the User Profile Properties but not modify them. However the only property you can modify is the Current User's profile picture. Source article: http://msdn.microsoft.com/en-us/library/jj920104.aspx

The REST API expects the image to be in the arraybuffer format in order to be set. To convert an image to arraybuffer, we will be using the XMLHttpRequest object

The XMLHttpRequest object allows us to specify the format in which we want the content to be downloaded. The available options are: arraybuffer, blob, json, text, document and some other browser specific formats.

Complete documentation for the XMLHttpRequest object:
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest

Also a very good article on how to use the XMLHttpRequest object:
https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest

A very important point to note is that XMLHttpRequest will work with cross domain images only if the server which is hosting the images allows cross domain requests to be made.

Modern browsers support cross-site requests by implementing the web applications working group's Access Control for Cross-Site Requests standard.  As long as the server is configured to allow requests from your web application's origin, XMLHttpRequest will work.  Otherwise, an INVALID_ACCESS_ERR exception is thrown.

For the sake of simplicity, we will be using the images hosted in the same domain as SharePoint itself so we do not have to worry about cross domain requests.

1) Set Current User's UserProfile Picture using the REST API:




2) Set Current User's UserProfile Picture using the .NET Managed Client Object Model:


This is relatively easy as the SetMyProfilePicture managed method expects the image to be a System.IO.Stream. 

This code assumes you are working with SharePoint Online/Office 365. If you are working with an On-Premise deployment, you do not need to use the SharePointOnlineCredentials class. You can simply create an instance of the NetworkCredentials class for the authentication.

13 comments:

Anonymous said...

Hi Vardhaman ,
Thanks for your post. But in my scenario I am interested to use the set current login credential , not hard code.
Is there any Idea to implement this functionality for current Login. Below is my used code
ClientContext clientContext = new ClientContext("http://abcd:88/sites/my/");
SecureString passWord = new SecureString();

clientContext.Credentials = new NetworkCredential("Username", "Password", "Domain");
var peopleManager = new PeopleManager(clientContext);

Stream fs = FileUpload1.PostedFile.InputStream;
peopleManager.SetMyProfilePicture(fs);
clientContext.ExecuteQuery();

Regards,
vinod

Vardhaman Deshpande said...

Hi Vinod,

Are you on On-Premise SharePoint 2013 or Office 365?

If you are On-Premise, you can use the following:

clientContext.Credentials = CredentialCache.DefaultNetworkCredentials;

chaithra N.V Moolya said...

Hi Vardhanman,
Thanks for the post. I have a query. I don't have sharepoint installed in my system. Inorder to use Microsoft.Sharepoint.Userprofiles ,can i download this dll and place it in a folder and reference this dll to visual studio. Will that work for me or installation of sharepoint is must. Please help Or Can i do any alternative?

Vardhaman Deshpande said...

@Chaithra,

Yes you can do that as this is a Client Side API and does not require SharePoint server to be installed.

Anonymous said...

This doesn't work in IE9 as there is no arraybuffer support?

Vardhaman Deshpande said...

Yes. You can find the browser compatibility of ArrayBuffer over here:
https://developer.mozilla.org/en-US/docs/Web/API/ArrayBuffer#Browser_compatibility

Marko Lokasaari said...

Hi Vardhaman
Thanx for a great blogg. How can I get for example the Company-property for all users? I'm about to create a InfoPath form where you can pick the Company

Suresh Lakum said...

Hi,
Vardhman what if I want to achieve same for cross-domain?

Thanks.

Vardhaman Deshpande said...

@Marko Please see this post: http://www.vrdmn.com/2013/07/sharepoint-2013-get-userprofile.html

@Suresh I don't think cross domain photo upload is supported yet in the API.

John Koser said...

Thanks for your very good post. It sounds like it may not be possible with JSOM to update another users profile picture (Office 365). Do you know if it can be done?
-John

Vardhaman Deshpande said...

Hi John, thanks!

And you are right there doesn't seem to be a way to set another user's photo with JSOM.

BARNITA said...

Hi Vardhaman,
Please help me with the following question:
"How to get user profile property for profile pic using rest api?"
Thanks.

Vardhaman Deshpande said...

Hi Barnita,

Please see this post: Get UserProfile Properties with REST API