微软规划器 API returns HTTP 500
Microsoft planner API returns HTTP 500
我正在尝试使用在 Azure 门户中具有 Group.Read.All
和 Group.ReadWrite.All
权限的已注册应用程序,通过 GraphServiceClient
读取单个计划的所有计划任务。
我已经尝试使用 Microsoft.Graph
和 Microsoft.Graph.Beta
包,但在调用任何计划程序 api 端点时,我总是会收到 InternalServerError。
使用以下代码设置 GraphServiceClient
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create("ClientId")
.WithTenantId("TenantId")
.WithClientSecret("ClientSecret")
.Build();
ClientCredentialProvider clientCredentialProvider = new ClientCredentialProvider(confidentialClientApplication);
GraphServiceClient graphClient = new GraphServiceClient(clientCredentialProvider);
工作正常。使用
呼叫群组 api
try
{
Task<IGraphServiceGroupsCollectionPage> groups = graphClient.Groups
.Request()
.GetAsync();
groups.Wait();
foreach (var item in groups.Result)
{
Console.WriteLine(item.DisplayName);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
也有效。但是调用规划器API
try
{
Task<PlannerPlan> plan = graphClient.Planner.Plans["PlanId"]
.Request()
.GetAsync();
plan.Wait();
Console.WriteLine(plan.Result.Title);
}
catch (Exception e)
{
Console.WriteLine(e);
}
仅抛出预期 “/taskApi”应用程序中的服务器错误。
An unhandled exception was generated during the execution of the
current web request. Information regarding the origin and location of
the exception can be identified using the exception stack trace below.
[NullReferenceException: Object reference not set to an instance of an
object.]
Microsoft.Office.Tasks.Service.S2SProxies.FederatedGraph.FederatedGraphService.DeserializeFederatedGraphObject(String
json) +35
Microsoft.Office.Tasks.Service.S2SProxies.FederatedGraph.d__51.MoveNext()
+1385 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task
task) +60
Microsoft.Office.Tasks.Service.S2SProxies.FederatedGraph.d__47.MoveNext()
+509
[FederatedGraphProxyException: Error getting graph object]
Microsoft.Office.Tasks.Service.CorrelationSafeAsync.ExecuteSynchronously(Func`2
asyncFunction, CancellationToken cancellationToken) +294
Microsoft.Office.Tasks.Service.UserAccountManager.AadUserAccountManager.GetExternalUserInfoInternal(IdentityClaim
claim) +520
[InvalidOperationException: Unexpected error retrieving graph object]
Microsoft.Office.Tasks.Service.UserAccountManager.AadUserAccountManager.GetExternalUserInfoInternal(IdentityClaim
claim) +1288
Microsoft.Office.Tasks.Service.UserAccountManager.AadUserAccountManager.EnsureUser(String
displayName, Boolean isLogin, CancellationToken cancellationToken,
IdentityClaim[] claims) +1013
Microsoft.Office.Tasks.Service.Authentication.AuthenticationModuleBase.EnsureUserAndSetCurrentUserProvider(HttpContextBase
httpContext, IUserAuthentication currentUser) +936
Microsoft.Office.Tasks.Service.Authentication.AuthenticationModuleBase.HandleAuthenticatedUser(HttpContextBase
httpContextBase, IUserAuthentication currentUser) +168
Microsoft.Office.Tasks.Service.Authentication.AuthenticationModuleBase.AuthorizeRequest(Object
sender, EventArgs e) +1867
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
+223 System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +213 System.Web.HttpApplication.ExecuteStep(IExecutionStep
step, Boolean& completedSynchronously) +91
虽然我必须更改身份验证提供程序,但可以使用我的 Microsoft 帐户。
我的代码中缺少什么吗?
编辑:工作代码
感谢@Jim Xu,我的代码可以正常工作了。对于任何 运行 遇到相同问题的人,这里是工作示例。
我必须将客户端密码添加到所有请求的 headers,但它仍然有效。
IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
.Create("CLientId")
.WithTenantId("TenantId")
.Build();
String[] scopes = new String[] { "Group.Read.All", "Group.ReadWrite.All" };
Func<DeviceCodeResult, Task> deviceCodeReadyCallback = async dcr => await Console.Out.WriteLineAsync(dcr.Message);
DeviceCodeProvider authProvider = new DeviceCodeProvider(publicClientApplication, scopes, deviceCodeReadyCallback);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
IGraphServiceGroupsCollectionRequest groupRequest = graphClient.Groups.Request();
groupRequest.Headers.Add(new HeaderOption("client_secret", "ClientSecrect"));
Task<IGraphServiceGroupsCollectionPage> groups = groupRequest.GetAsync();
groups.Wait();
foreach (var item in groups.Result)
{
Console.WriteLine(item.DisplayName);
}
根据您的代码,您使用客户端凭据流程调用 Microsoft 计划 API。换句话说,您使用应用程序权限来调用 Microsoft Graph Plan API。这是错误的。根据official document,我们可以直接使用Delegated权限来调用API。所以你会得到错误。
关于如何用SDK调用api,请参考以下代码(本人在控制台应用测试)
配置您的 Azure AD 应用程序
一个。打开 allowPublicClient
设置
b。更新 API 权限。请添加要求委派权限:Group.Read.All
、Group.ReadWrite.All
代码
string clientId = "";
string tenantId = "";
IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantId)
.Build();
var scopes = new string[] { "Group.Read.All", "Group.ReadWrite.All" };
Func<DeviceCodeResult, Task> deviceCodeReadyCallback = async dcr => await Console.Out.WriteLineAsync(dcr.Message);
DeviceCodeProvider authProvider = new DeviceCodeProvider(publicClientApplication, scopes, deviceCodeReadyCallback);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
Task<PlannerPlan> plan = graphClient.Planner.Plans["Lc1LT2z1aEqnACVeA8KtIGUABIeE"]
.Request()
.GetAsync();
plan.Wait();
Console.WriteLine("The plan tiltel : " + plan.Result.Title);
Console.ReadLine();
我正在尝试使用在 Azure 门户中具有 Group.Read.All
和 Group.ReadWrite.All
权限的已注册应用程序,通过 GraphServiceClient
读取单个计划的所有计划任务。
我已经尝试使用 Microsoft.Graph
和 Microsoft.Graph.Beta
包,但在调用任何计划程序 api 端点时,我总是会收到 InternalServerError。
使用以下代码设置 GraphServiceClient
IConfidentialClientApplication confidentialClientApplication = ConfidentialClientApplicationBuilder
.Create("ClientId")
.WithTenantId("TenantId")
.WithClientSecret("ClientSecret")
.Build();
ClientCredentialProvider clientCredentialProvider = new ClientCredentialProvider(confidentialClientApplication);
GraphServiceClient graphClient = new GraphServiceClient(clientCredentialProvider);
工作正常。使用
呼叫群组 apitry
{
Task<IGraphServiceGroupsCollectionPage> groups = graphClient.Groups
.Request()
.GetAsync();
groups.Wait();
foreach (var item in groups.Result)
{
Console.WriteLine(item.DisplayName);
}
}
catch (Exception e)
{
Console.WriteLine(e);
}
也有效。但是调用规划器API
try
{
Task<PlannerPlan> plan = graphClient.Planner.Plans["PlanId"]
.Request()
.GetAsync();
plan.Wait();
Console.WriteLine(plan.Result.Title);
}
catch (Exception e)
{
Console.WriteLine(e);
}
仅抛出预期 “/taskApi”应用程序中的服务器错误。
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
[NullReferenceException: Object reference not set to an instance of an object.]
Microsoft.Office.Tasks.Service.S2SProxies.FederatedGraph.FederatedGraphService.DeserializeFederatedGraphObject(String json) +35
Microsoft.Office.Tasks.Service.S2SProxies.FederatedGraph.d__51.MoveNext() +1385 System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw() +31
System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) +60
Microsoft.Office.Tasks.Service.S2SProxies.FederatedGraph.d__47.MoveNext() +509[FederatedGraphProxyException: Error getting graph object]
Microsoft.Office.Tasks.Service.CorrelationSafeAsync.ExecuteSynchronously(Func`2 asyncFunction, CancellationToken cancellationToken) +294
Microsoft.Office.Tasks.Service.UserAccountManager.AadUserAccountManager.GetExternalUserInfoInternal(IdentityClaim claim) +520[InvalidOperationException: Unexpected error retrieving graph object] Microsoft.Office.Tasks.Service.UserAccountManager.AadUserAccountManager.GetExternalUserInfoInternal(IdentityClaim claim) +1288
Microsoft.Office.Tasks.Service.UserAccountManager.AadUserAccountManager.EnsureUser(String displayName, Boolean isLogin, CancellationToken cancellationToken, IdentityClaim[] claims) +1013
Microsoft.Office.Tasks.Service.Authentication.AuthenticationModuleBase.EnsureUserAndSetCurrentUserProvider(HttpContextBase httpContext, IUserAuthentication currentUser) +936
Microsoft.Office.Tasks.Service.Authentication.AuthenticationModuleBase.HandleAuthenticatedUser(HttpContextBase httpContextBase, IUserAuthentication currentUser) +168
Microsoft.Office.Tasks.Service.Authentication.AuthenticationModuleBase.AuthorizeRequest(Object sender, EventArgs e) +1867
System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +223 System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step) +213 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +91
虽然我必须更改身份验证提供程序,但可以使用我的 Microsoft 帐户。
我的代码中缺少什么吗?
编辑:工作代码
感谢@Jim Xu,我的代码可以正常工作了。对于任何 运行 遇到相同问题的人,这里是工作示例。 我必须将客户端密码添加到所有请求的 headers,但它仍然有效。
IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
.Create("CLientId")
.WithTenantId("TenantId")
.Build();
String[] scopes = new String[] { "Group.Read.All", "Group.ReadWrite.All" };
Func<DeviceCodeResult, Task> deviceCodeReadyCallback = async dcr => await Console.Out.WriteLineAsync(dcr.Message);
DeviceCodeProvider authProvider = new DeviceCodeProvider(publicClientApplication, scopes, deviceCodeReadyCallback);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
IGraphServiceGroupsCollectionRequest groupRequest = graphClient.Groups.Request();
groupRequest.Headers.Add(new HeaderOption("client_secret", "ClientSecrect"));
Task<IGraphServiceGroupsCollectionPage> groups = groupRequest.GetAsync();
groups.Wait();
foreach (var item in groups.Result)
{
Console.WriteLine(item.DisplayName);
}
根据您的代码,您使用客户端凭据流程调用 Microsoft 计划 API。换句话说,您使用应用程序权限来调用 Microsoft Graph Plan API。这是错误的。根据official document,我们可以直接使用Delegated权限来调用API。所以你会得到错误。
关于如何用SDK调用api,请参考以下代码(本人在控制台应用测试)
配置您的 Azure AD 应用程序
一个。打开
allowPublicClient
设置b。更新 API 权限。请添加要求委派权限:
Group.Read.All
、Group.ReadWrite.All
代码
string clientId = "";
string tenantId = "";
IPublicClientApplication publicClientApplication = PublicClientApplicationBuilder
.Create(clientId)
.WithTenantId(tenantId)
.Build();
var scopes = new string[] { "Group.Read.All", "Group.ReadWrite.All" };
Func<DeviceCodeResult, Task> deviceCodeReadyCallback = async dcr => await Console.Out.WriteLineAsync(dcr.Message);
DeviceCodeProvider authProvider = new DeviceCodeProvider(publicClientApplication, scopes, deviceCodeReadyCallback);
GraphServiceClient graphClient = new GraphServiceClient(authProvider);
Task<PlannerPlan> plan = graphClient.Planner.Plans["Lc1LT2z1aEqnACVeA8KtIGUABIeE"]
.Request()
.GetAsync();
plan.Wait();
Console.WriteLine("The plan tiltel : " + plan.Result.Title);
Console.ReadLine();