I have already written a post about displaying user profile picture in SharePoint hosted apps. At the end of the post, I mentioned an alternate way of doing this. This post is about the pros and cons of both the approaches, the issues I faced while using them in provider hosted app and how I resolved them.
- UserPhoto.aspx:
This page is relative to a site collection and resides in _layouts folder. The problem is, the image takes a lot of time to reflect here. I tested in an O365 provider hosted app and the image took more than a day to appear. I also noticed that unless the user visits the site collection where the app is deployed, this page will not update. This is logical as the page is relative to a site collection. But the good part is, it shows a default image unless the actual image appears (or if the user has not uploaded any image). - GetPersonalPhoto service:
I noticed this service when my O365 top bar got updated with the new look, the one with the app launcher. It uses the following URL to fetch the user image:
https://outlook.office365.com/owa/service.svc/s/GetPersonaPhoto?email=garima@something.onmicrosoft.com&size=HR120x120
I have tested with the following values of “size” parameter:- HR48x48
- HR64x64
- HR96x96
- HR120x120
The good part is, the image gets reflected as soon as they are uploaded and I also find it faster than userphoto.aspx. But the problem is, it does not show any default image if the user has not uploaded any picture. So, in my case, nothing is visible where the image tag is. Basically, it returns a transparent 1×1 image in this case.
Solution:
Use GetPersonalPhoto service and check if it is returning a 1×1 image. If yes, then replace it with a default image. This default image can be a sample picture present in your project or you can even use userphoto.aspx as it will return a default image in such scenarios. To check the image size, I used naturalWidth and naturalHeight properties of HTML5. The sample javascript code is present below. This code is for a view where multiple user images are present, you can modify it for single person view also.
$(document).ready(function () { $(".userImages").on("load", function () { console.log("Height: " + this.naturalHeight); if (this.naturalHeight < 2 || this.naturalWidth < 2) { this.src = {default picture path}; } }); });
Here “userImages” is the class used in <img> tag.
As empty images have size 1×1, therefore, I checked naturalHeight < 2.
I tested this code and it is working fine in provider hosted app. Make sure, your tenant is updated (with the new top bar) before using this approach. Also, this works only in browsers which support HTML5.
Hope this helps!
Pingback: User profile picture in SP hosted app | My SharePoint Learnings
There is no needs to test the size of the profile picture. Just use another default image at the same position as the profile picture. When the profile picture doesn’t load for any reason, the default image will show. Otherwise the profile image will cover the default image. That is whole point why the service return 1 pixel image when there is profile picture.
Thanks for the tip Mike, will try this tip
I’m assuming that userphoto is used for hosted SharePoint and getpersonalphoto for O365, for add-ins? However not sure if it’s a bug but in add-ins but userphoto tries to get photo from https://hostweb-{appid}.sharepoint.com/_layouts/15/userphoto.aspx which doesn’t exist with the {appid} included and throws a 500 error. Thoughts?
I guess you are trying to use it in sharepoint hosted app, which has appid in host url. You need to get host web url from query string param to form userphoto.aspx . For more details check here https://msdn.microsoft.com/en-us/library/office/jj163816.aspx
Or you can use SP.RequestExecutor.js to query for host web url.
Garima, I’ve built a very similar app which retrieves a users photo (from SP user profile), their name and job title. I’ve also added a link to change the user photo, via https://portal.office.com/userphoto.
I’m finding the original picture that loads gets cached in the browser (IE, Edge and Chrome), after the user changes their picture at the above URL.
It doesn’t matter if I change my app to retrieve the photo from Delve or Outlook, the caching still occurs. In fact, the profile picture in the top right hand corner of SharePoint Online (pulled from Delve) actually changes, leaving the app user profile picture cached.
Have you ever experienced this? Any chance you know a way around this issue?
Hi Steve, are you facing the same issue with both methods? Could you try and append a query string parameter to the URL so that the generated image is not cached? It is one way around this issue.
https://docs.microsoft.com/en-us/exchange/client-developer/web-service-reference/sizerequested
Value Meaning
HR48x48 The image is 48 pixels high and 48 pixels wide.
HR64x64 The image is 64 pixels high and 64 pixels wide.
HR96x96 The image is 96 pixels high and 96 pixels wide.
HR120x120 The image is 120 pixels high and 120 pixels wide.
HR240x240 The image is 240 pixels high and 240 pixels wide.
HR360x360 The image is 360 pixels high and 360 pixels wide.
HR432x432 The image is 432 pixels high and 432 pixels wide.
HR504x504 The image is 504 pixels high and 504 pixels wide.
HR648x648 The image is 648 pixels high and 648 pixels wide.