Reputation: 469
Having a look into Microsoft's Graph API, specifically looking at the angular example called 'O365-Angular-Microsoft-Graph-Connect' - https://github.com/OfficeDev/O365-Angular-Microsoft-Graph-Connect. Have successfully registered the app and installed the dependencies. However when running the app I am correctly seeing all the user's details apart from the image, (all the users in our O365 tenancy have an image). Debugging the app it appears the response received from the api is full of '�' symbols which suggests an encoding issue somewhere. When using the graph API explorer I get the image returned fine which suggests this is the app. Any ideas of how to remedy this so the example app works? The index html page is correctly UTF-8 encoded so the app looks correct to me which suggests an issue with the API, however as the graph API explorer gives me the correct image that suggests it's the app.
Any ideas on how to pull through the image in the example app provided by Microsoft?
Other thoughts are that as the example screenshot provided by MS uses a placeholder image this part of the app is simply not working yet.
Upvotes: 1
Views: 7355
Reputation: 1680
Hope this helps: https://stackoverflow.com/a/69391807/3786343
In this answer, I've used angular current version 12 and microsoft graph api v1.0.
Upvotes: 0
Reputation: 1
Had the same issue all day!
Main points to consider
When using a standard response such as Response.text() or Response.json() you will receive
SyntaxError: Unexpected token � in JSON at position 0
fetch("https://graph.microsoft.com/v1.0/me/photo/$value", requestOptions)
.then(response => response.blob())
.then(result => setUserImage(window.URL.createObjectURL(result)))
.catch(error => console.log('error', error));
Upvotes: 0
Reputation: 61
TypeScript code to get the photo
@observable private photo: string;
getPhoto('/me/photos/48x48/$value').then((photo) => {
this.photo = photo;
}).catch(error => {});
}
<img className='br24' src={this.photo}/>
export function getPhoto(query: string): Promise<string> {
let promise = new Promise<string>((resolve, reject) => {
adalContext.AuthContext.acquireToken("https://graph.microsoft.com", (error, token) => {
if (error) {
reject(error);
} else {
if (query.indexOf('/') != 0)
query = '/' + query;
let u = `https://graph.microsoft.com/v1.0${query}`;
axios.get(u, { headers: { Authorization: `Bearer ${token}`, encoding: null }, responseType: 'arraybuffer' }).then(
val => {
let photo = 'data:' + val.headers['content-type'] + ';base64,' + new Buffer(val.data, 'binary').toString('base64');
resolve(photo);
},
error => {
reject(error);
}
);
}
});
});
return promise;
}
Upvotes: 1
Reputation: 3015
This is an older question but I hope this will be helpful to some (C#).
Catch the incoming array as a byteArray and convert it to a base64string. These can easily be converted to images or saved in DB's
public static async void GetPhoto(HttpClient client, string id)
{
var resp = await client.GetAsync(@"https://graph.microsoft.com/v1.0/users/" + id + "/photos/240x240/$value");
var buffer = await resp.Content.ReadAsByteArrayAsync();
var byteArray = buffer.ToArray();
string base64String = Convert.ToBase64String(byteArray);
if(base64String != null && base64String != "")
{
//Insert into database or convert.
}
}
Upvotes: 1
Reputation: 604
After playing with Postman (Chrome extension for playing with REST etc.) it is very clear that the returned image is ok and "normal" and that our code must make sure it is saved as it should be.
Afterwards I hacked this NodeJS code that can, maybe, help another newbies like me:)
/**
/users/<id | userPrincipalName>/photo/$value
*/
function getUserPhoto(accessToken, userId, callback) {
var options = {
host: 'graph.microsoft.com',
path: "/v1.0/users/" +userId + "/photo/$value",
method: 'GET',
headers: {
Authorization: 'Bearer ' + accessToken
}
};
https.get(options, function (response) {
response.setEncoding('binary'); /* This is very very necessary! */
var body = '';
response.on('data', function (d) {
body += d;
});
response.on('end', function () {
var error;
if (response.statusCode === 200) {
/* save as "normal image" */
fs.writeFile('./public/img/image.jpeg', body, 'binary', function(err){
if (err) throw err
console.log('Image saved ok')
})
/* callback - for example show in template as base64 image */
callback(new Buffer(body, 'binary').toString('base64'));
} else {
error = new Error();
error.code = response.statusCode;
error.message = response.statusMessage;
// The error body sometimes includes an empty space
// before the first character, remove it or it causes an error.
body = body.trim();
error.innerError = JSON.parse(body).error;
callback(error, null);
}
});
}).on('error', function (e) {
callback(e, null);
});
}
Upvotes: 1