Forum Discussion

Atul Moghe's avatar
Atul Moghe
Copper Contributor
Aug 10, 2017
Solved

How to get user photo in C# using Graph API?

I am building a bot which shows user the searched user photo and other information. Rest of the information is being fetched properly other than user's photo.

 

I am trying to get user photo by using below URL. Graph explorer shows the user's photo using this URL.

https://graph.microsoft.com/v1.0/users/{userid}/photo/$value

 

I am using below code to get the image and assign it as URL to image card in my bot.

        private async Task<string> GetPhoto(HttpClient client, string id)
        {
           
            var resp = await client.GetAsync("https://graph.microsoft.com/v1.0/users/{id}/photo/$value");
            var buffer = await resp.Content.ReadAsByteArrayAsync();
            var byteArray = buffer.ToArray();

            string base64String = Convert.ToBase64String(byteArray);

            Trace.WriteLine($"converted base 64 string! =>=>=>=> {base64String}");
            return base64String;

        }

is it the right way to fetch and show the user photo in C#?

  • I found the solution to this issue in one of the Richard diZerega's sample bots. Following is the way you display the user's photo in bot.

     

    Get the byte array of the user's photo by using Graph API.

     

    // Extension method
    public static async Task<byte[]> GetStreamWithAuthAsync(this HttpClient client, string accessToken, string endpoint)
            {
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
                using (var response = await client.GetAsync(endpoint))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        var stream = await response.Content.ReadAsStreamAsync();
                        byte[] bytes = new byte[stream.Length];
                        stream.Read(bytes, 0, (int)stream.Length);
                        return bytes;
                    }
                    else
                        return null;
                }
            }

    Assign the above byte array with the prefix "data&colon;image/png;base64," and assign it to image URL property.

     

     

    // Get the users profile photo from the Microsoft Graph
    var bytes = await new HttpClient().GetStreamWithAuthAsync(token, "https://graph.microsoft.com/v1.0/me/photo/$value");
    var pic = "data&colon;image/png;base64," + Convert.ToBase64String(bytes);
    
    ThumbnailCard card = new ThumbnailCard()
     {
        Title = $"{((JValue)jItem["Subject"]).Value}",
        Subtitle = jItem.SelectToken("sender.emailAdress.name").ToString(),
        Text = jItem.SelectToken("body.content").ToString(),
        Images = new List<CardImage>()
        {
              new CardImage()
              {
                    Url= pic
              }
        }
     };
     return card;

     

     

     

3 Replies

  • jvl-dk's avatar
    jvl-dk
    Copper Contributor

    Atul Moghe 

     

    WIth recent updates to Microsoft.Graph api (summer 2020), this approach is pretty clean:

    public static async Task<System.Drawing.Image> GetMePhotoAsync()
            {
                try
                {
                    // GET /me
                    Stream photoresponse = await graphClient.Me.Photo.Content.Request().GetAsync();
    
                    if (photoresponse != null)
                    {
                        MemoryStream ms = new MemoryStream();
                        photoresponse.CopyTo(ms);
                        System.Drawing.Image i = System.Drawing.Image.FromStream(ms);
    
                        return i;
                    }
                    else
                    { return null; }
                }
                catch (ServiceException ex)
                {
                    Console.WriteLine($"Error getting signed-in user profilephoto: {ex.Message}");
                    return null;
                }
            }
  • Atul Moghe's avatar
    Atul Moghe
    Copper Contributor

    I found the solution to this issue in one of the Richard diZerega's sample bots. Following is the way you display the user's photo in bot.

     

    Get the byte array of the user's photo by using Graph API.

     

    // Extension method
    public static async Task<byte[]> GetStreamWithAuthAsync(this HttpClient client, string accessToken, string endpoint)
            {
                client.DefaultRequestHeaders.Add("Authorization", "Bearer " + accessToken);
                client.DefaultRequestHeaders.Add("Accept", "application/json");
                using (var response = await client.GetAsync(endpoint))
                {
                    if (response.IsSuccessStatusCode)
                    {
                        var stream = await response.Content.ReadAsStreamAsync();
                        byte[] bytes = new byte[stream.Length];
                        stream.Read(bytes, 0, (int)stream.Length);
                        return bytes;
                    }
                    else
                        return null;
                }
            }

    Assign the above byte array with the prefix "data&colon;image/png;base64," and assign it to image URL property.

     

     

    // Get the users profile photo from the Microsoft Graph
    var bytes = await new HttpClient().GetStreamWithAuthAsync(token, "https://graph.microsoft.com/v1.0/me/photo/$value");
    var pic = "data&colon;image/png;base64," + Convert.ToBase64String(bytes);
    
    ThumbnailCard card = new ThumbnailCard()
     {
        Title = $"{((JValue)jItem["Subject"]).Value}",
        Subtitle = jItem.SelectToken("sender.emailAdress.name").ToString(),
        Text = jItem.SelectToken("body.content").ToString(),
        Images = new List<CardImage>()
        {
              new CardImage()
              {
                    Url= pic
              }
        }
     };
     return card;

     

     

     

    • tmoulton's avatar
      tmoulton
      Copper Contributor

      Atul Moghe

       

      How would you do this for a single page web app using PHP or MSAL.js

      I can get the details data, but not the actual photo 

Resources