Microsoft Graph .NET SDK V5获取用户头像流时类型转换失败问题求助
大家好,我遇到了一个升级Microsoft Graph SDK后的棘手问题,想请各位帮忙排查一下。
我有一个基础的Razor Pages Web应用,通过Microsoft Graph获取用户信息和头像。在使用Microsoft.Graph V4版本时,用ClientSecretCredential认证一切正常,用户信息和头像都能成功获取,还能把头像流转成MemoryStream后显示在页面上。
V4版本项目配置
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net9.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> <UserSecretsId>aspnet-GraphTest-f0c950ea-9c29-4d6d-af44-7711be58959f</UserSecretsId> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.2" NoWarn="NU1605" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.2" NoWarn="NU1605" /> <PackageReference Include="Microsoft.Graph" Version="4.54.0" /> <PackageReference Include="Microsoft.Identity.Web" Version="3.7.1" /> <PackageReference Include="Microsoft.Identity.Web.UI" Version="3.7.1" /> </ItemGroup> </Project>
V4版本后台代码
public async Task OnGet() { var options = new ClientSecretCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud }; var credentials = new ClientSecretCredential(<tenantid>, <clientid>, <clientsecret>, options); var graphServiceClient = new GraphServiceClient(credentials, new string[] { "https://graph.microsoft.com/.default" }); var user = await graphServiceClient.Users[<userid>].Request().GetAsync(); ViewData["Name"] = user.DisplayName; using var photoStream = await graphServiceClient.Users[<userid>].Photo.Content.Request().GetAsync(); ViewData["Photo"] = Convert.ToBase64String(((MemoryStream?)photoStream)?.ToArray()); }
但当我把Microsoft.Graph升级到V5.71.0版本,并且按照新语法去掉.Request()后,获取到的头像流类型发生了变化,直接转换会抛出InvalidCastException错误。
V5版本项目配置
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net9.0</TargetFramework> <Nullable>enable</Nullable> <ImplicitUsings>enable</ImplicitUsings> <UserSecretsId>aspnet-GraphTest-f0c950ea-9c29-4d6d-af44-7711be58959f</UserSecretsId> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="9.0.2" NoWarn="NU1605" /> <PackageReference Include="Microsoft.AspNetCore.Authentication.OpenIdConnect" Version="9.0.2" NoWarn="NU1605" /> <PackageReference Include="Microsoft.Graph" Version="5.71.0" /> <PackageReference Include="Microsoft.Identity.Web" Version="3.7.1" /> <PackageReference Include="Microsoft.Identity.Web.UI" Version="3.7.1" /> </ItemGroup> </Project>
V5版本后台代码
public async Task OnGet() { var options = new ClientSecretCredentialOptions { AuthorityHost = AzureAuthorityHosts.AzurePublicCloud }; var credentials = new ClientSecretCredential(<tenantid>, <clientid>, <clientsecret>, options); var graphServiceClient = new GraphServiceClient(credentials, new string[] { "https://graph.microsoft.com/.default" }); var user = await graphServiceClient.Users[<userid>].GetAsync(); ViewData["Name"] = user.DisplayName; using var photoStream = await graphServiceClient.Users[<userid>].Photo.Content.GetAsync(); ViewData["Photo"] = Convert.ToBase64String(((MemoryStream?)photoStream)?.ToArray()); }
错误发生在这一行:ViewData["Photo"] = Convert.ToBase64String(((MemoryStream?)photoStream)?.ToArray());
具体错误信息如下:
System.InvalidCastException
HResult=0x80004002
Message=Unable to cast object of type 'Http2ReadStream' to type 'System.IO.MemoryStream'.
Source=System.Private.CoreLib
StackTrace:
at System.Runtime.CompilerServices.CastHelpers.ChkCast_Helper(Void* toTypeHnd, Object obj)
at GraphTest.Pages.IndexModel.d__2.MoveNext() in C:\Users\ojmcf\source\repos\GraphTest\GraphTest\Pages\Index.cshtml.cs:line 43
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.ExecutorFactory.NonGenericTaskHandlerMethod.d__2.MoveNext()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.d__29.MoveNext()
at Microsoft.AspNetCore.Mvc.RazorPages.Infrastructure.PageActionInvoker.d__31.MoveNext()
我找了一圈没发现有类似问题的讨论,难道只有我遇到这个情况吗?或者有没有大佬已经找到解决办法了?麻烦指点一下!
备注:内容来源于stack exchange,提问作者OjM

