如何在C#中通过Graph API使用UPN更新用户头像?(UserID可用UPN不可用)
解决Graph API使用UPN更新用户头像失败的问题
我在C#中使用Graph API更新用户头像时,传入UserID可以正常执行,但传入User Principal Name(UPN)则失败。实现代码如下:
public async Task<bool> UpdateProfilePicture(string userId, string imagePath) { try { using (var stream = new FileStream(imagePath, FileMode.Open)) { await GraphClient.Users[userId].Photo.Content.PutAsync(stream); Console.WriteLine("Profile picture updated successfully."); return true; } } catch (ODataError odataError) { Console.WriteLine($"OData error details:"); Console.WriteLine($"Code: {odataError.Error?.Code}"); Console.WriteLine($"Message: {odataError.Error?.Message}"); throw; } catch (ServiceException ex) { Console.WriteLine($"Error updating profile picture: {ex.Message}"); return false; } }
调用时出现无法识别用户的错误(对应提供的错误截图)。
问题原因
核心问题是UPN包含@这类URL特殊字符,直接作为路径参数传入时未被正确编码,导致Graph API无法解析出正确的用户标识。
解决方法
方法1:对UPN进行URL编码
在传入GraphClient.Users[]前,使用Uri.EscapeDataString()对用户标识(UserID或UPN)进行编码,处理特殊字符:
public async Task<bool> UpdateProfilePicture(string userIdOrUpn, string imagePath) { try { // 对用户标识进行URL编码,兼容UserID和UPN string encodedIdentifier = Uri.EscapeDataString(userIdOrUpn); using (var stream = new FileStream(imagePath, FileMode.Open)) { await GraphClient.Users[encodedIdentifier].Photo.Content.PutAsync(stream); Console.WriteLine("Profile picture updated successfully."); return true; } } catch (ODataError odataError) { Console.WriteLine($"OData error details:"); Console.WriteLine($"Code: {odataError.Error?.Code}"); Console.WriteLine($"Message: {odataError.Error?.Message}"); throw; } catch (ServiceException ex) { Console.WriteLine($"Error updating profile picture: {ex.Message}"); return false; } }
方法2:先通过UPN获取UserID再操作
这种方法更稳定,避免编码问题:先通过UPN查询用户的ID,再用ID执行更新操作:
public async Task<bool> UpdateProfilePicture(string userIdOrUpn, string imagePath) { try { // 根据标识查询用户详情,获取用户ID var user = await GraphClient.Users[userIdOrUpn].GetAsync(); if (user == null) { Console.WriteLine("User not found."); return false; } using (var stream = new FileStream(imagePath, FileMode.Open)) { await GraphClient.Users[user.Id].Photo.Content.PutAsync(stream); Console.WriteLine("Profile picture updated successfully."); return true; } } catch (ODataError odataError) { Console.WriteLine($"OData error details:"); Console.WriteLine($"Code: {odataError.Error?.Code}"); Console.WriteLine($"Message: {odataError.Error?.Message}"); throw; } catch (ServiceException ex) { Console.WriteLine($"Error updating profile picture: {ex.Message}"); return false; } }
额外注意事项
- 确保应用已被授予正确权限:需要
User.ReadWrite.All(应用权限,可操作所有用户)或User.ReadWrite(委托权限,仅能操作当前用户),且权限已通过管理员同意。 - 验证UPN正确性:确认传入的UPN在Azure AD中是唯一且存在的。
内容的提问来源于stack exchange,提问作者Ashish Prajapati
相关产品推荐
相关产品推荐

