Search code examples
c#.netmicrosoft-graph-apimicrosoft-graph-sdks

Getting all profile pictures using Microsoft Graph in C#


I am creating an application in .NET Core 6, where I need to get all profile pictures of users in my org, using the Microsoft Graph SDK. The application is using an app-only token.

First I have tried to do this, and only get one picture, using the users ID:

public static async Task<Task<ProfilePhoto?>> GetUsersPhotos(string id)
        {
            // Ensure client isn't null
            _ = _appClient ??
                throw new NullReferenceException("Graph has not been initialized for app-only auth");
            try
            {
                var requestUserPhoto = _appClient.Users[id].Photo.GetAsync();
                return requestUserPhoto;
            }
            catch (ODataError odataError)
            {
                Console.WriteLine(odataError.Error.Code);
                Console.WriteLine("Error Message: " + odataError.Error.Message);
                return null;
            }
        }

This returns an OData error, which it seems I am not able to inspect. I have no problems getting other data using the SDK. I have only been able to find getting the signed in users profile picture, in the Microsoft documentation.

The end result should be a FileStream or some other format which I can save as a JPG on a server.


Solution

  • You can directly return the stream through Content request builder

    public static async Task<Stream> GetUsersPhotos(string id)
        {
            // Ensure client isn't null
            _ = _appClient ??
                throw new NullReferenceException("Graph has not been initialized for app-only auth");
            try
            {
                return await _appClient.Users[id].Photo.Content.GetAsync();
            }
            catch (ODataError odataError)
            {
                Console.WriteLine(odataError.Error.Code);
                Console.WriteLine("Error Message: " + odataError.Error.Message);
                return null;
            }
        }
    

    And save the content to a file

    using (var stream = await GetUsersPhotos(user.Id))
    {
        using (var fileStream = new FileStream(sourceFileName, FileMode.Create, FileAccess.Write))
        {
            await stream.CopyToAsync(fileStream);
        }
    }