使用Microsoft Graph获取当前用户Planner全部计划的异常问题
解决Graph SDK获取Planner全部计划不全的问题
我之前也碰到过这个一模一样的问题!你用的gc.Me.Planner.Plans.Request().GetAsync()其实只能拿到你直接作为成员加入的Planner计划,但Planner网页端的「全部计划」还包含了你所在Office 365组拥有的计划——哪怕你不是该计划的直接成员,只要你是对应组的成员,这些计划就会显示在列表里。
要拿到和「全部计划」完全一致的结果,需要分两步获取然后合并去重:
所需权限
首先确保你的应用已经申请了以下委托权限:
Planner.Read.All或Planner.ReadWrite.AllGroup.Read.All
具体实现代码
using Microsoft.Graph; using Microsoft.Graph.Models; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; public async Task<List<PlannerPlan>> GetAllPlannerPlansAsync(GraphServiceClient gc) { var allPlans = new List<PlannerPlan>(); // 第一步:获取当前用户直接加入的计划 var userPlansPage = await gc.Me.Planner.Plans.Request().GetAsync(); await PageIterator<PlannerPlan, PlannerPlanCollectionResponse> .CreatePageIterator(gc, userPlansPage, plan => { allPlans.Add(plan); return true; }) .IterateAsync(); // 第二步:获取用户所属所有组的计划 var groupsPage = await gc.Me.MemberOf.GraphGroup.Request().GetAsync(); var groups = await PageIterator<Group, GroupCollectionResponse> .CreatePageIterator(gc, groupsPage, group => { return true; }) .IterateAsync(); foreach (var group in groups) { try { var groupPlansPage = await gc.Groups[group.Id].Planner.Plans.Request().GetAsync(); await PageIterator<PlannerPlan, PlannerPlanCollectionResponse> .CreatePageIterator(gc, groupPlansPage, plan => { allPlans.Add(plan); return true; }) .IterateAsync(); } catch (ServiceException ex) { // 跳过无权限访问或无Planner计划的组 if (ex.StatusCode != System.Net.HttpStatusCode.Forbidden && ex.StatusCode != System.Net.HttpStatusCode.NotFound) { throw; } } } // 去重:避免同一计划被重复添加(比如用户既是组成员又是计划直接成员) var uniquePlans = allPlans.GroupBy(p => p.Id).Select(g => g.First()).ToList(); return uniquePlans; }
关键说明
- 分页处理:用
PageIterator确保获取所有分页结果,Graph API默认每次最多返回100条数据,直接调用GetAsync()可能只能拿到第一页内容。 - 去重逻辑:同一个计划可能同时出现在用户直接计划列表和组计划列表,通过计划
Id分组去重就能得到唯一的计划集合。 - 异常处理:部分组可能没有创建Planner计划,或者应用没有访问该组计划的权限,捕获对应异常跳过即可,不影响整体流程。
这样获取到的uniquePlans就和Planner网页端「全部计划」展示的内容完全一致啦!
内容的提问来源于stack exchange,提问作者leopik
相关产品推荐
相关产品推荐

