如何使用Microsoft.Graph SDK或User.Identity获取个人资料图片



我已经在Microsoft Azure中使用quickstart项目成功地实现了身份验证,但现在我无法获得登录用户的个人资料图片。

我试过使用Microsoft.Graph SDK,但Photo一直在获得null

IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create(ClientId)
.WithTenantId(TenantId)
.WithClientSecret(ClientSecret)
.Build();
AuthorizationCodeProvider authProvider = new AuthorizationCodeProvider(confidentialClientApplication);
// Create an authentication provider.
ClientCredentialProvider authenticationProvider = new ClientCredentialProvider(confidentialClientApplication);
// Configure GraphServiceClient with provider.
GraphServiceClient graphServiceClient = new GraphServiceClient(authenticationProvider);
var users = await graphServiceClient.Users.Request().GetAsync();

我也尝试过获取一个id和.Select("Photo")的特定用户,但结果是相同的

var temp = await graphServiceClient.Users[user_id]
.Request()
.Select("Photo")
.GetAsync();

也许我的实施是错误的,任何帮助或建议都将不胜感激。

当我研究这个问题时,我经常偶然发现这篇文章。我想我应该使用Graph API 5.6.0发布我的解决方案。它似乎与上面的有所不同。在下面的代码中,this.Me.Photo是null,我相信即使它不是null,它也只包含关于图像的元数据(宽度、高度等(。要获得流,你需要构建一个ContentRequestBuilder并调用GetAsync来获得图像流。

我这样做的方法是基于我在应用程序初始化中创建的GraphServiceClient服务创建Microsoft.Graph.Me.Photo.Value.ContentRequestBuilder。有关创建GraphServiceClient的详细信息,请参阅在ASP.NET Core Blazor WebAssembly中使用Graph API。

代码:

UserInfo.razor.cs

using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Components;
using Microsoft.Graph;
using Microsoft.Graph.Models;
using System.Security.Cryptography;
using PhotoContentRequestBuilder = Microsoft.Graph.Me.Photo.Value.ContentRequestBuilder;
namespace GdbRaiser.Pages;
[Authorize]
public partial class UserInfo
{
[Inject]
public GraphServiceClient? Client { get; set; }
private User? Me { get; set; }
public string? PhotoBytes { get; set; }
protected override async Task OnInitializedAsync()
{
_ = this.Client?.Me ?? throw new NullReferenceException("Client.Me must not be null");
this.Me = await this.Client.Me.GetAsync();
PhotoContentRequestBuilder photoRequest = new(new Dictionary<string, object>(), this.Client.RequestAdapter);
using Stream? photo = await photoRequest.GetAsync();
using StreamReader? reader = photo is null
? null
: new StreamReader(new CryptoStream(photo, new ToBase64Transform(), CryptoStreamMode.Read));
this.PhotoBytes = reader is null
? null
: await reader.ReadToEndAsync();
}
}

更新:经过更多的研究,它变得更容易了。您可以直接使用客户端:

protected override async Task OnInitializedAsync()
{
_ = this.Client?.Me ?? throw new NullReferenceException("Client.Me must not be null");
this.Me = await this.Client.Me.GetAsync();
using Stream? photo = await this.Client.Me.Photo.Content.GetAsync();
using StreamReader? reader = photo is null
? null
: new StreamReader(new CryptoStream(photo, new ToBase64Transform(), CryptoStreamMode.Read));
this.PhotoBytes = reader is null
? null
: await reader.ReadToEndAsync();
}

用户信息.razor

@page "/Me"
@using System.Reflection;
@inject IConfiguration Configuration
@code {
public static readonly string? Route = typeof(UserInfo).GetCustomAttribute<RouteAttribute>(true)?.Template;
public static readonly string Title = "Debug";
public static readonly string[] Icons = { "fa fa-bug-slash" };
}
<PageTitle>@(Configuration.GetValue<string>("AppTitle")) - @Title</PageTitle>
<h3>Hello @Me?.DisplayName</h3>
<table>
<tbody>
<tr>
<td class="text-right"><label class="mr-2">Account Name:</label></td>
<td>@(Me?.UserPrincipalName ?? "null")</td>
</tr>
<tr>
<td class="text-right"><label class="mr-2">Phone:</label></td>
<td>@(Me?.MobilePhone ?? "null")</td>
</tr>
<tr>
<td class="text-right"><label class="mr-2">Phone:</label></td>
<td>
@if (PhotoBytes is null)
{
@("null")
}
else
{
<img src="data:image;base64,@PhotoBytes" />
}
</td>
</tr>
</tbody>
</table>

要将照片作为流获取,可以使用以下代码

using (var photoStream = await graphServiceClient.Users[user_id].Photo.Content
.Request()
.GetAsync())
{
// your code       
}

最新更新