You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 03:03:13