Occasionally, we get requests asking how to get the user photo using the Graph SDK. This blog post will show you how to do that in a WPF application but I will also show you a method for getting the photo and saving it to disk with a .Net console application.
You can download the sample project here: https://github.com/RayGHeld/GraphClient_GetUserPhoto This project also utilizes the Authentication Provider code in this blog post.
You will need to modify the AuthSettings.cs file with your own app registration settings. Specifically, the client_id, tenant_id and redirect_uri values. But first, please ensure you have created an app registration for this project. The only permissions needed for this is the Microsoft Graph User.Read permission, which is enabled by default when you create an app registration in Azure. For the redirect uri, in the Authentication blade, I just selected a mobile platform for MSAL only.
Running the project is really basic. When loading, it will prompt you for credentials and then immediately, display the user photo for the logged in user. There is a requirement for the photo to exist — you must have an O365 license associated with the user and that photo uploaded to the user. If not, then no photo will exist. Otherwise, you will get a simple screen that shows the photo, name and title for the user like so:
Please note: this may or may not be my actual photo 😉
namespace GraphClient_GetPhoto_WPF { /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window { private static GraphServiceClient graphClient = GraphClient.ServiceClient( AuthenticationProviders.InteractiveAuthentication.AuthenticationProvider ); public MainWindow() { InitializeComponent(); Get_Me(imagePhoto, userInfo); } static async void Get_Me(System.Windows.Controls.Image img, System.Windows.Controls.Label label) { User u = null; try { u = await graphClient.Me.Request().GetAsync(); label.Content = $"{u.DisplayName}\n{u.JobTitle}"; } catch ( Exception ex ) { Console.WriteLine( $"Error getting user info: {ex.Message}" ); } try { using ( Stream stream = await graphClient.Users[u.Id].Photo.Content.Request().GetAsync() ) { BitmapImage bitmap = new BitmapImage(); bitmap.BeginInit(); bitmap.StreamSource = stream; bitmap.EndInit(); img.Source = bitmap; } } catch ( Exception ex ) { Console.WriteLine( $"Error getting image: {ex.Message}" ); } } } }
WPF is a little bit tricky since I have to pass in the control in order to be able to update it. I referenced this great blog for how to do this since I am not a WPF developer: https://www.c-sharpcorner.com/UploadFile/mahesh/using-xaml-image-in-wpf/
Now, in a console application, here is how you can simply download the image if needed:
static async Task Get_Photo(String path) { try { using ( Stream stream = await graphClient.Me.Photo.Content.Request().GetAsync() ) { System.Drawing.Image image = System.Drawing.Image.FromStream( stream ); image.Save( path ); Console.WriteLine( $"Image saved to: {path}" ); } } catch ( Exception ex ) { Console.WriteLine( $"Error getting and saving image: {ex.Message}" ); } } }
If performing this from the Graph Explorer tool, you must use the $value query parameter to get the image to display in that tool like so:
And that is it. As demonstrated, with a little bit of work, you can get the graph client to retrieve and display or save a user photo if one exists for the user.
Thank you this was very helpful there are not enough examples like this in the documentation.