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!