MS Graph v5.42.0分页获取邮件时修改页大小无效问题咨询
MS Graph v5.42.0分页获取邮件时无法修改页大小的问题
我使用MS Graph v5.42.0分页获取邮件,希望从包含70封邮件的文件夹中获取50封邮件。第一页按预期返回30封,但将第二页的页大小(Top)改为20后,仍返回30封。请问分页时无法修改页大小吗?
问题代码
int maxItemSize = 50; int pageSize = 30; if (maxItemSize <= pageSize) pageSize = maxItemSize; string itemSearchFilter = GetItemFilters(messageClasses, onlyMailsWithAttachments, ignoredDomains, archiveSize, archiveDate, archiveAge, setFilterIgnoreSignedItems, setFilterNotKdxArchived, setFilterKdxArchived); string expandValue = string.Format("singleValueExtendedProperties($filter = id eq '{0}' or id eq '{1}' or id eq '{2}' or id eq '{3}' or id eq '{4}')", MessageClassPropertyID1, DisplayToPropertyID1, DisplayCcPropertyID1, NativeBodyPropertyID, MessageSizePropertyID1); List<Message> messages = new List<Message>(); var messagesResponse = await GraphServiceClient .Users[CurrentMailBoxAddress] .MailFolders[FolderId] .Messages .GetAsync((requestConfiguration) => { requestConfiguration.QueryParameters.Top = pageSize; requestConfiguration.QueryParameters.Expand = new string[] { expandValue }; requestConfiguration.QueryParameters.Filter = itemSearchFilter; }); while (messagesResponse.Value != null) { messages.AddRange(messagesResponse.Value); if (messages.Count() >= maxItemSize) break; else { int messagesToBeRetrieved = maxItemSize - messages.Count(); if (messagesToBeRetrieved <= pageSize) { // Resets the page size for the last request pageSize = messagesToBeRetrieved; } // If OdataNextLink has a value, there is another page if (!string.IsNullOrEmpty(messagesResponse.OdataNextLink)) { messagesResponse = await GraphServiceClient .Users[CurrentMailBoxAddress] .MailFolders[FolderId] .Messages .WithUrl(messagesResponse.OdataNextLink) .GetAsync((requestConfiguration) => { requestConfiguration.QueryParameters.Top = pageSize; requestConfiguration.QueryParameters.Expand = new string[] { expandValue }; requestConfiguration.QueryParameters.Filter = itemSearchFilter; }); } else { // No more results, exit loop break; } } }
原因分析
当使用WithUrl()方法传入@odata.nextLink进行分页请求时,该链接已经包含了第一页请求中的所有查询参数(包括$top=30)。此时在requestConfiguration中修改Top参数不会生效,因为Graph SDK会优先使用链接中已有的参数,忽略你在配置中设置的新值。
解决方案
方案1:修改分页链接中的$top参数
手动解析OdataNextLink,替换其中的$top值为所需的页数,再传入WithUrl():
if (!string.IsNullOrEmpty(messagesResponse.OdataNextLink)) { // 修改链接中的$top参数,若需更严谨可使用URL解析库处理 string modifiedNextLink = messagesResponse.OdataNextLink.Replace("$top=30", $"$top={pageSize}"); messagesResponse = await GraphServiceClient .Users[CurrentMailBoxAddress] .MailFolders[FolderId] .Messages .WithUrl(modifiedNextLink) .GetAsync((requestConfiguration) => { requestConfiguration.QueryParameters.Expand = new string[] { expandValue }; requestConfiguration.QueryParameters.Filter = itemSearchFilter; }); }
方案2:放弃@odata.nextLink,改用$skip参数(注意局限性)
如果查询结果总数不多,可以使用$skip跳过已获取的条目,同时设置新的$top:
// 替换原循环中的分页逻辑 int skippedItems = 0; while (messages.Count < maxItemSize) { int currentPageSize = Math.Min(pageSize, maxItemSize - messages.Count); var pageResponse = await GraphServiceClient .Users[CurrentMailBoxAddress] .MailFolders[FolderId] .Messages .GetAsync((requestConfiguration) => { requestConfiguration.QueryParameters.Top = currentPageSize; requestConfiguration.QueryParameters.Skip = skippedItems; requestConfiguration.QueryParameters.Expand = new string[] { expandValue }; requestConfiguration.QueryParameters.Filter = itemSearchFilter; }); if (pageResponse.Value == null || !pageResponse.Value.Any()) break; messages.AddRange(pageResponse.Value); skippedItems += pageResponse.Value.Count; }
注意:Graph API对$skip有数量限制(通常超过1000条后不支持),邮件总数较大时建议优先用方案1。
方案3:调整初始页大小(最简单的业务适配)
如果业务允许,直接将初始页大小设为maxItemSize,一次性获取所需邮件:
int maxItemSize = 50; int pageSize = maxItemSize; // 直接设置为目标数量 // 后续请求逻辑保持不变,第一页即可返回最多50封邮件
内容的提问来源于stack exchange,提问作者maffer1
相关产品推荐
相关产品推荐

